2011-09-13 50 views
3

呃,我該如何解釋這一個......可能是一個簡單的問題,但我的腦子被炸了。如何使用C#在.Net中的類型化對象列表中選擇對象屬性的所有值0123#

假設我有這個類:

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的列表,用戶ID對象和SomeIntValue.ToString()對應於輸入列表中的每個項目。

哇,我真的希望這是有道理的。請讓我知道,如果這不清楚,我會提供更多的細節。我真的希望這是我忽視的圖書館中的東西。

我的任何想法都可以做到這一點?

+0

感謝大家的回答!請檢查我的後續問題在這裏:http://stackoverflow.com/questions/7396781/architecturally-speaking-how-should-i-replace-an-extremely-large-switch-statemen – longda

回答

2

通常,當嘗試創建通用列表操作符時,最終會重新實現LINQ已經爲您提供的功能。

下面是你以後有什麼(無AwesomeHelper功能)的LINQ代碼:

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(); 

我希望這有助於。

+0

感謝您的回答!我相信這說明了我最初提出的另一個方面,具體來說,我如何將所選屬性傳遞給一個函數。我非常喜歡這個答案,我會在我的項目中探索一下。我會讓你知道它是如何發生的,我可能會在稍後將它作爲我選擇的答案進行切換。再次感謝! – longda

3

可以實現它作爲一個擴展的方法:

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 
      }); 
+0

謝謝!是的,我想我完全想到了這個。 – longda

+0

@longda:你沒有將此標記爲選定答案的任何特定原因? – BrokenGlass

+0

再次感謝您的回覆。我切換了標記的答案,因爲Enigmativity具有創建選擇器函數的代碼。 – longda

相關問題