2012-11-05 81 views
4

我有一些定義的對象,每個都有一個名爲「CreateDate」的屬性。從內部查找最大值列表<T>

是否可以編寫一個單一的泛型方法來從我指定的對象中選擇最高日期?

我試圖對此使用一種通用的方法,但編譯器不喜歡它,當我嘗試指定屬性名稱。

我試圖實現這些方針的東西...

private static DateTime GetLastDate<T>(List<T> data) 
{ 
    // Unfortunately, this is not allowed... 
    return 
     (from d in data 
     orderby d.CreateDate 
     select d.CreateDate).FirstOrDefault(); 
} 

回答

10

最好的方法是創建具有特定功能的接口,並擁有所有的類都實現該接口:

public interface ICreated 
{ 
    public DateTime CreateDate {get;} 
} 

然後你就可以確保所有接受實現該接口的項目:

​​

如果這實際上不是一個選項(可能因爲您無法修改該類以使其實現接口或集合來包裝基礎類型),那麼您可以使用dynamic。我會極力阻止你做這個,因爲它真的不是很好的設計,這將是更慢,這是相當容易打破,但它可以工作:

private static DateTime GetLastDate(IEnumerable<dynamic> input) 
{ 
    return input.Max(d=>d.CreateDate); 
} 
1

你可以在一個基類封裝CREATEDATE財產(如BaseClass的),並且還水木清華這樣

private static DateTime GetLastDate<T>(List<T> data) where T : BaseClass 
{ 
    ... 
} 
2

您可以使用反射的字符串值,這樣得到的屬性名稱:

你需要這個方法通過字符串值,以獲得實際的屬性,如果你正在計劃使用通用stu的分配如果你有興趣把這個地方放在一個地方,你可以重新使用它。

// Add ' using System.Reflection; ' on top 
public static object GetPropertyValue(object o, string propertyName) 
     { 
      Type type = o.GetType(); 
      PropertyInfo info = type.GetProperty(propertyName); 
      object value = info.GetValue(o, null); 
      return value; 
     } 

根據該方法,你可以做,而不是說是不是爲你工作的這段代碼:

private static DateTime GetLastDate<T>(List<T> data) 
    { 
     object value = (from d in data 
      orderby GetPropertyValue(d, "CreateDate") 
      select GetPropertyValue(d, "CreateDate")).FirstOrDefault(); 

     return DateTime.Parse(value.ToString()); 
    } 

應該完全正常工作,現在,它會留通用只是你的方式希望它是。

0

我只是做了這一點,在我的擴展類

public static object GetPropertyValue(this object o, string propertyName) 
    { 
     Type type = o.GetType(); 

     try 
     { 
      PropertyInfo info = (from x in type.GetProperties() where x.Name.ToLower() == propertyName.ToLower() select x).First(); 
      object value = info.GetValue(o, null); 
      return value; 
     } 
     catch (Exception ex) 
     { 
      return default(object); 
     } 
    } 

    public static T GetFieldValue<T>(this object o, string propertyName) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T> 
    { 
     try 
     { 
      var val = GetPropertyValue(o, propertyName); 
      return (T)val; 
     } 
     catch (Exception ex) 
     { 
      return default(T); 
     } 
    } 

創建了一個通用的方法和我這是怎麼使用它...

var max_cust_id = (string)(from m in final_list.Skip((int)offset) 
            orderby m.GetPropertyValue(identityField) 
            select m.GetPropertyValue(identityField)).Max();