簡體   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