2015-07-28 4 views
0

У меня есть абстрактный класс с именем 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

EDIT: Моя реальной целью является для чтения классов свойств, как показано ниже, а затем возвращает строку типа «? Страница = 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; } 
} 

Так что я не хотел писать метод для каждого класса для генерации строки запроса. Я думаю, что могу поместить метод шаблона в базовый класс OptionParameter и создать строку с помощью свойств свойств класса и свойств атрибута.

+2

'GenerateQueryStringWithParameters (это);' не будет компилировать. Кроме того, зачем объявлять его как метод расширения, когда вы вызываете его статически? – haim770

+0

Это оригинальный тип был необязательным. Но я хочу называть этот метод расширения для каждого класса, который наследует абстрактный класс OptionalParameter. Фактически, моя настоящая цель - создать шаблонный метод и назвать его в общем случае. –

+0

Что вы подразумеваете под «Как создать общий шаблонный метод для каждого параметра OptionParameter». Вы хотите, чтобы каждый тип, наследующий от OptionalParameter, имел свой собственный метод GenerateQueryStringWithParameters? –

ответ

1

Параметр типа в GenerateQueryStringWithParameters<T>() бесполезен, так как вы всегда вызываете метод как параметр типа OptionalParameter. Поэтому вы можете переписать метод как GenerateQueryStringWithParameters(this OptionalParemeter optionalParameter).

Для того чтобы сгенерировать строку запроса, необходимо использовать отражение для циклического перехода через свойства класса optionalParameter и проверить, есть ли у них EntityOptionalParameter. Предполагая, что вы можете получить доступ к ParameterName через свойство EntityOptionalParameter.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() 
} 
Смежные вопросы