Search for maximum value from list <T>

I have a certain number of objects, each of which has a "CreateDate" property.

Is it possible to write one, general method for selecting the highest date from the object that I am specifying?

I tried to use a general approach to this, but the compiler does not like it when I try to specify a property name.

I tried to achieve something in this direction ...

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
source share
4 answers

The best way would be to create an interface with certain functionality and implement all the classes in this interface:

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

Then you can make sure that all accepted elements implement this interface:

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

If this is really not an option (perhaps because you cannot change the class to implement an interface or collection to wrap the base type), you can use dynamic . I would be very discouraged that you are doing this, as this is really not a good design, it will be much slower, and it is more susceptible to hacking, but it can work:

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

You can use Reflection to get the property name from string values ​​as follows:

You will need this method to get the actual property by the string value if you plan to work with allocations of common things that may be of interest in putting this place in another place that you can reuse.

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

With this method, you can do this instead of code that doesn't work for you:

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

Now it should work perfectly, and it will remain general as you want.

+2
source

You can encapsulate the CreateDate property in a base class (e.g. BaseClass) and do something like this

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

I just did it and created a generic method in my extension class

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

And this is how I used it ...

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

Source: https://habr.com/ru/post/1444208/


All Articles