6

我定义了许多对象,每个对象都有一个名为“CreateDate”的属性。

是否可以编写一个通用的方法来从我指定的对象中选择最高日期?

我试图对此使用通用方法,但是当我尝试指定属性名称时编译器不喜欢它。

我试图在这些方面取得一些成就......

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();
}
4

4 回答 4

11

最好的方法是创建一个具有特定功能的接口,并让所有类都实现该接口:

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

然后您可以确保所有接受的项目都实现该接口:

private static DateTime GetLastDate<T>(IEnumerable<T> input) where T : ICreated
{
    return input.Max(d=>d.CreateDate);
}

如果这真的不是一个选项(可能是因为您无法修改类以使其实现接口或集合来包装基础类型),您可以使用dynamic. 我非常不鼓励你这样做,因为它真的不是好的设计,它会慢得多,而且很容易被破坏,但它可以工作:

private static DateTime GetLastDate(IEnumerable<dynamic> input)
{
    return input.Max(d=>d.CreateDate);
}
于 2012-11-05T21:01:47.787 回答
2

您可以使用反射通过字符串值获取属性名称,如下所示:

您将需要此方法通过字符串值获取实际属性,如果您计划使用分配的通用内容,您可能有兴趣将其放在可以重用它的地方。

// 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());
    }

它现在应该可以正常工作了,而且它会按照你想要的方式保持通用。

于 2012-11-05T23:31:31.340 回答
1

您可以将 CreateDate 属性封装在基类(例如 BaseClass)中,然后像这样

private static DateTime GetLastDate<T>(List<T> data) where T : BaseClass
{
     ...
}
于 2012-11-05T21:02:15.180 回答
1

我只是这样做并在我的扩展类中创建了一个通用方法

 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();
于 2017-02-08T07:38:36.013 回答