从List <t> </t>中查找最大值

时间:2012-11-05 20:57:52

标签: c# list c#-4.0 generic-list

我定义了许多对象,每个对象都有一个名为“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 个答案:

答案 0 :(得分:10)

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

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

答案 1 :(得分:2)

您可以使用Reflection按字符串值获取属性名称,如下所示:

你需要这个方法来获取字符串值的实际属性,如果你打算使用你可能感兴趣的一些通用的东西,你可以将它放在某个地方,你可以重复使用它。

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

它现在应该可以正常工作,并且它将按照您希望的方式保持通用。

答案 2 :(得分:1)

您可以将CreateDate属性封装在基类(例如BaseClass)中并像这样执行

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

答案 3 :(得分: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();