【问题标题】:Finding max value from within List<T>从 List<T> 中查找最大值
【发布时间】:2012-11-05 20:57:52
【问题描述】:

我定义了许多对象,每个对象都有一个名为“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();
}

【问题讨论】:

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


    【解决方案1】:

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

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

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-10-21
            • 1970-01-01
            • 2020-10-15
            • 2011-11-30
            • 2014-09-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多