模板方法的通用扩展方法

时间:2015-07-28 14:16:13

标签: c# generics inheritance

我有一个名为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

创建通用模板方法

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

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基类中放置一个模板方法,并通过类属性类型和属性属性创建字符串。

1 个答案:

答案 0 :(得分:1)

GenerateQueryStringWithParameters<T>()中的类型参数无用,因为您始终将该方法称为类型参数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()
}