繁体   English   中英

如何使用C#在.Net中的类型对象列表中选择对象属性的所有值

[英]How to select all the values of an object's property on a list of typed objects in .Net with C#

呃,我该如何解释这一个...可能是一个简单的问题,但我的思绪是炒的。

假设我有这个课程:

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<SomeBigExternalDTO>();
foo = GetMyListOfSomeBigExternalDTO();

public static List<MyResult> AwesomeHelper(List<SomeBigExternalDTO> 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()对应于输入列表中的每个项目。

哇,我真的希望这是有道理的。 如果不清楚,请告诉我。我会提供更多详情。 我真的希望这是我忽略的库中的东西。

我有什么想法可以实现这个目标吗?

可以将其实现为扩展方法:

public static IEnumerable<MyResult> AwesomeHelper(this IEnumerable<SomeBigExternalDTO> input, 
                                                  Func<SomeBigExternalDTO, int> 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
             });

通常在尝试创建通用列表运算符时,最终会重新实现LINQ已经为您提供的功能。

这是你所追求的LINQ代码(没有AwesomeHelper函数):

var results = list.Select(l => new MyResult()
{
    UserId = l.UserId,
    ResultValue = l.SomeDecimalValue.ToString()
}).ToList();

相当简单。

如果您想要按照要求拥有AwesomeHelper函数,那么它看起来像这样:

public static List<MyResult> AwesomeHelper(
    List<SomeBigExternalDTO> input,
    Func<SomeBigExternalDTO, object> 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<SomeBigExternalDTO, object> selector)
    {
        return new MyResult()
        {
            UserId = input.UserId,
            ResultValue = selector(input).ToString()
        };
    }
}

现在呼叫代码清晰,灵活,简洁。 这里是:

var results = (
        from item in list
        select item.ToMyResult(x => x.SomeLongValue)
    ).ToList();

我希望这有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM