【问题标题】:Generic Extension Methods with Template Method带有模板方法的通用扩展方法
【发布时间】:2015-07-29 04:57:46
【问题描述】:

我有一个名为 OptionalParameters 的抽象类作为其他参数类的基类。

public abstract class OptionalParameter
{
    //Template Method 
    public string GenerateQueryString()
    {
        return OptionalParameterExtensions.GenerateQueryStringWithParameters<OptionalParameter>(this);
    }
}

我有一个基类作为 OptionalParameter。 TimeEntriesParameters 继承自该基类。

public class TimeEntriesParameters : OptionalParameter
{
//Some Properties
}

所以我想用我继承的类属性生成一个查询字符串。然后我为此编写了一个扩展方法。

public static class OptionalParameterExtensions
{
    public static string GenerateQueryStringWithParameters<T>(this T optionalParameters) where T : OptionalParameter
    {
        //Generates and returns query string with properties of T type
    }
}

对继承自基类的类应用上述结构后,其用法如下。

TimeEntriesParameters parameters = new TimeEntriesParameters();
string queryString = parameters.GenerateQueryString();

如何为每个 OptionalParameter 创建一个通用模板方法

编辑:我的真正目的是读取类属性如下,然后返回一个字符串,如 "?page=1&fromDate=20150728" 等。

public class TimeEntriesParameters : OptionalParameter
{
    [EntityOptionalParameter(ParameterName="page")]
    public int Page { get; set; }

    [EntityOptionalParameter(ParameterName = "fromDate")]
    public DateTime FromDate { get; set; }

    [EntityOptionalParameter(ParameterName = "fromTime")]
    public DateTime FromTime { get; set; }

    [EntityOptionalParameter(ParameterName = "ToDate")]
    public DateTime ToDate { get; set; }

    [EntityOptionalParameter(ParameterName = "ToTime")]
    public DateTime ToTime { get; set; }

    [EntityOptionalParameter(ParameterName = "SortOrder")]
    public Enumerations.SortOrder SortOrder { get; set; }

    [EntityOptionalParameter(ParameterName = "UserId")]
    public int UserId { get; set; }
}

所以我不想为每个类编写一个方法来生成查询字符串。我想我可以在 OptionalParameter 基类中放置一个模板方法,并通过类属性类型和属性属性创建字符串。

【问题讨论】:

  • GenerateQueryStringWithParameters&lt;this&gt;(this); 不会编译。另外,静态调用时为什么要声明为扩展方法?
  • 它的原始类型是可选参数。但是我想为每个继承 OptionalParameter 抽象类的类调用这个扩展方法。其实我真正的目的是创建一个模板方法并通用调用它。
  • “如何为每个 OptionalParameter 创建通用模板方法”是什么意思。您是否希望从 OptionalParameter 继承的每种类型都有自己的 `GenerateQueryStringWithParameters' 方法?
  • 我想使用 GenerateQueryStringWithParameters 方法作为模板方法。因为我有一个带有 ParameterName 属性的属性。在我的模板方法中,我将查看属性类型,然后如果属性不为空,那么我将向查询字符串添加一个参数。因此,我不想为继承自 OptionalParameter 类的所有类型编写自己的方法。
  • @FernandoMatsumoto 我已经编辑了我的问题并放置了一个示例继承类。

标签: c# generics inheritance


【解决方案1】:

GenerateQueryStringWithParameters&lt;T&gt;() 中的类型参数没用,因为您总是将方法作为类型参数OptionalParameter 调用。因此,您可以将方法重写为GenerateQueryStringWithParameters(this OptionalParemeter optionalParameter)

为了生成查询字符串,您需要使用反射循环遍历optionalParameter 类中的属性,并检查它们是否有EntityOptionalParameter。假设您可以通过属性EntityOptionalParameter.ParameterName 访问ParameterName,您可以执行以下操作:

public static string GenerateQueryStringWithParameters(this OptionalParameter optionalParameter)
{
    var props = optionalParameter.GetType().GetProperties()
        .Select(x => new { Prop = x, Attr = x.GetCustomAttribute<EntityOptionalParameter>() })
        .Where(x => x.Attr != null); // Get all properties that have the attribute

    var sb = new StringBuilder("?");
    var first = true;
    foreach(var prop in props) // Loop through properties
    {
        if (first)
        {
            first = false;
        }
        else
        {
            sb.Append("&")
        }
        sb.Append(prop.Attr.ParameterName); // Append property name
        sb.Append("=");
        sb.Append(prop.Prop.GetValue(optionalParameter)); // Append property value
    }
    return sb.ToString()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    相关资源
    最近更新 更多