从List<T>中找到最大值

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个回答

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

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

现在它应该完美地工作了,而且它将保持通用,就像你想要的那样。


1
您可以将CreateDate属性封装在一个基类中(例如BaseClass),然后执行以下操作。
private static DateTime GetLastDate<T>(List<T> data) where T : BaseClass
{
     ...
}

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接