0

私が取得しようとしているのは、エンティティからのプロパティであり、値を合計します。私はジェネリックを使用しており、エンティティの型とプロパティの名前は実行時に認識されます。次の (簡略化された) コードは正常にコンパイルされますが、「オブジェクトがターゲット タイプと一致しません」というメッセージがスローされます。エンティティからプロパティを取得しようとするとき。コードは次のとおりです。

    public class SomeModel
    {
        public int ValueA { get; set; }
        public int ValueB { get; set; }
    }

    public class SomeViewModel
    {
        public int ViewValue { get; set; }
    }

    public class HomeController : Controller
    {

        public ActionResult Index()
        {
            IEnumerable<SomeModel> data = GetData();

            var result = SumValues(data, a => new SomeViewModel { ViewValue = a.ValueA });

            return Content(string.Format("Total is: {0}", result));
        }

        private int SumValues<T, TRes>(IEnumerable<T> data, Func<T, TRes> transformation)
        {
            var transformedData = data.Select(transformation);
            Type type = typeof(TRes);
            PropertyInfo property = type.GetProperty("ViewValue");
            IEnumerable<int> listOfValues = property.GetValue(transformedData, null) as IEnumerable<int>;
            var sum = listOfValues.Sum();

            return sum;
        }

        private IEnumerable<SomeModel> GetData()
        {
            var data = new List<SomeModel>();
            Random random;
            for (int i = 0; i < 1000; i++)
            {
                random = new Random(i);
                data.Add(new SomeModel { ValueA = random.Next(5,100), ValueB = random.Next(20,80) });
            }
            return data;
        }
    }

ここでは偽のデータを生成していますが、実際のアプリケーションは EF を使用してデータベースからデータを取得しています。ジェネリックは私にとって新しいので、正しい方向に私を向けるアドバイスをいただければ幸いです.

4

1 に答える 1

0

この行で:

IEnumerable<int> listOfValues = 
                       property.GetValue(transformedData, null) as IEnumerable<int>;

オブジェクトのViewValueプロパティの値を取得しようとしていますが、プロパティがありません。あなたができることの1つはこれです:List<SomeModel>List<SomeModel>ViewValue

IEnumerable<int> listOfValues = 
                       transformedData.Select(i => (int)property.GetValue(i, null));

ただし、ここでは必要ないため、反射を完全に回避することが、よりクリーンな解決策になります。

interface IViewValue
{
    int ViewValue { get; set; }
}

public class SomeViewModel : IViewValue
{
    public int ViewValue { get; set; }
}

private int SumValues<T, TRes>(IEnumerable<T> data, Func<T, TRes> transformation)
                                            where TRes : IViewValue
{
    var transformedData = data.Select(transformation);
    IEnumerable<int> listOfValues = transformedData.Select(i => i.ViewValue);
    var sum = listOfValues.Sum();

    return sum;
}
于 2013-03-14T14:26:03.810 に答える