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

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

これで完全に正常に動作するはずです。また、希望どおりの汎用性を維持できます。

于 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 に答える