2

私はジェネリックを初めて使用しますが、物事をDRYに保つためにジェネリックを使用する必要があることを知っています:)

多くの異なるタイプのリストをドロップダウン リスト コントロールで使用される共通のクラスに変換するクラスを作成しようとしていますが、それを機能させることはできません。以下の方法でこれを試すための2つのオプションを示しています。それぞれを機能させようとしています(foreachループとlinq)が、役に立ちません。

private static IEnumerable<ddlOptions> GetDDLOptionsViewModel<T>(List<T> genericList, string strPropName)
{
    // option A: ForEach loop
    Type type = genericList.GetType();
    var IdProperty = type.GetProperty("Id");
    var DisplayNameProp = type.GetProperty(strPropName);

    List<ddlOptions> options = new List<ddlOptions>();
    foreach (var l in genericList)
    {
        options.Add(new ddlOptions
            { 
                Id = IdProperty.GetValue(l, null), 
                DisplayName = DisplayNameProp.GetValue(l, null)
            });
    }
    return options;

    // option B - LINQ
    return from l in genericList
           select new ddlOptions
           {
               Id = l.Id,
               DisplayName = l.strPropName
           };
}
4

2 に答える 2

5

インターフェイスを使用しTてプロパティを含めるように制約し、型の安全性を維持してリフレクションを回避しながら、型 T のオブジェクトから特定のプロパティにアクセスするためにIda を使用できます。Func<T,string>

public interface IId
{
  string Id {get;}
}


private static IEnumerable<ddlOptions> GetDDLOptionsViewModel<T>
    (IEnumerable<T> list, Func<T,string> propAccess)
   where T:IId
{
   return list.Select(l => new DdlOption
    {
        Id = l.Id,
        DisplayName = propAccess(l)
    });
}
于 2012-12-19T04:27:04.420 に答える
2

さらに短く(LINQも)、1行と拡張メソッド:

public static IEnumerable<DdlOption> ToDdlOption<T>(this IEnumerable<T> genericList, string strPropName)
{
    return genericList.Select(l => new DdlOption
        {
            Id = l.Id,
            DisplayName = l.strPropName
        });
}

また、大文字でクラスに名前を付け、複数形を避けます。

ToArray()またはを呼び出して、LINQ クエリの結果を具体化することを忘れないでくださいToList()


プロパティ名をプロパティ ターゲット ラムダ式に変換するには:

public static Func<T, object> ToLambda<T>(this string propertyName)
{
    ParameterExpression param = Expression.Parameter(typeof(T), "x"); // x
    Expression property = Expression.Property(param, propertyName);   // x.PropertyName
    Func<T, object> lambda = Expression.Lambda<Func<T, object>>(      // x => x.PropertyName
            Expression.Convert(property, typeof(object)),
            param)
        .Compile();
    return lambda;
}

使用法:

// assuming class X { public string PropertyName { get; set; }
var lambda = "PropertyName".ToLambda<X>()
var x = new X { PropertyName = "Hi!" };
string value = lambda(x); // "Hi!"
于 2012-12-19T04:09:07.317 に答える