如何使用C#在.Net中的类型对象列表中选择对象属性的所有值
呃,我怎么解释这个…可能是一个简单的问题,但我的思绪是炒的。
假设我有这个课程:
public class NestedObject { public string NestedName { get; set; } public int NestedIntValue { get; set; } public decimal NestedDecimalValue { get; set; } } public class SomeBigExternalDTO { public int Id { get; set; } public int UserId { get; set; } public int SomeIntValue { get; set; } public long SomeLongValue { get; set; } public decimal SomeDecimalValue { get; set; } public string SomeStringValue { get; set; } public NestedObject SomeNestedObject { get; set; } // ... thousands more of these properties... inherited code }
我想填写的课程在这里:
public class MyResult { public int UserId { get; set; } // user id from above object public string ResultValue { get; set; } // one of the value fields from above with .ToString() executed on it }
我想要做的是创建一个帮助器来返回此对象列表中所有实例的属性值(我猜测的横截面是最好的方法):
var foo = new List(); foo = GetMyListOfSomeBigExternalDTO(); public static List AwesomeHelper(List input, SearchableProperty thePropertyIWant) { // some magic needs to happen here... }
这里棘手的部分是我想基于链接选择器动态传递属性(我不知道如何做到这一点):
var output = AwesomeHelper(GetMyListOfSomeBigExternalDTO(), x => x.SomeIntValue); var output2 = AwesomeHelper(GetMyListOfSomeBigExternalDTO(), x => x.SomeNestedObject.NestedIntValue);
这应该返回一个MyResult对象列表,其中UserId和SomeIntValue.ToString()对应于输入列表中的每个项目。
哇,我真的希望这是有道理的。 如果不清楚,请告诉我。我会提供更多详情。 我真的希望这是我忽略的库中的东西。
我有什么想法可以实现这一目标吗?
通常在尝试创建通用列表运算符时,最终会重新实现LINQ已经为您提供的内容。
这是你所追求的LINQ代码(没有AwesomeHelper
函数):
var results = list.Select(l => new MyResult() { UserId = l.UserId, ResultValue = l.SomeDecimalValue.ToString() }).ToList();
相当简单。
如果你想要一个你所要求的AwesomeHelper
函数,那么它看起来像这样:
public static List AwesomeHelper( List input, Func selector) { return input .Select(i => new MyResult() { UserId = i.UserId, ResultValue = selector(i).ToString() }) .ToList(); }
调用代码如下所示:
var results = AwesomeHelper(list, x => x.SomeIntValue);
但是,对我来说,这比LINQ选项的可读性低。 现在有一些魔法正在形成,很难弄清楚是什么。
我有一个替代方案,可以给你两全其美。
首先,定义一个名为ToMyResult
的扩展方法,该方法将单个SomeBigExternalDTO
实例映射到具有字段选择器的单个MyResult
,如下所示:
public static class AwesomeHelperEx { public static MyResult ToMyResult( this SomeBigExternalDTO input, Func selector) { return new MyResult() { UserId = input.UserId, ResultValue = selector(input).ToString() }; } }
现在呼叫代码清晰,灵活,简洁。 这里是:
var results = ( from item in list select item.ToMyResult(x => x.SomeLongValue) ).ToList();
我希望这有帮助。
您可以将其实现为扩展方法:
public static IEnumerable AwesomeHelper(this IEnumerable input, Func intMapper) { foreach (var item in input) yield return new MyResult() { UserId = item.UserId, ResultValue = intMapper(item) }; }
现在您可以像这样使用它:
var output = GetMyListOfSomeBigExternalDTO().AwesomeHelper( x => x.SomeIntValue); var output2 = GetMyListOfSomeBigExternalDTO().AwesomeHelper( x => x.SomeNestedObject.NestedIntValue);
话虽如此 – 不要那么做 – 看起来你正在重新发明Linq已经提供给你的东西, 你只能使用Linq做同样的事情 :
var output = GetMyListOfSomeBigExternalDTO().Select( x=> new MyResult() { UserId = item.UserId, ResultValue = x.SomeIntValue }); var output2 = GetMyListOfSomeBigExternalDTO().Select( x=> new MyResult() { UserId = item.UserId, ResultValue = x.SomeNestedObject.NestedIntValue });