2011-09-13 1 views
3

ああ、どうすれば説明できますか?おそらく簡単な質問ですが、私の心は揚げられています。.NETの型付きオブジェクトのリストでオブジェクトのプロパティの値をすべて選択するには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); 

そして、これはユーザーIDでMyResultオブジェクトのリストを返す必要がありますし、 SomeIntValue.ToString()は、入力リストの各項目に対応しています。

うわー、これは理にかなっていると思います。これが明確でない場合は私にお知らせください。私は詳細を提供します。私はこれが私が見落とした図書館に焼いたものだと本当に期待しています。

私はこれを達成するための任意のアイデアですか?

+0

回答ありがとうございます!私のフォローアップの質問をここでチェックしてください:http://stackoverflow.com/questions/7396781/architecturally-speaking-how-should-i-replace-an-extremely-large-switch-statemen – longda

答えて

2

多くの場合、汎用リスト演算子を作成しようとすると、LINQがすでに提供しているものが再実装されます。かなり単純な

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

は、ここでは、(AwesomeHelper機能なし)後にしている何のためにLINQコードです。

あなたが要求したとして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オプションより読み取り可能です。今ではいくつかの魔法が成就しており、何を解決するのは難しいです。

私はあなたに両方の世界のベストを与える代替手段があります。

まず、このように、フィールドセレクタを有する単一MyResultに単一SomeBigExternalDTOインスタンスをマッピングToMyResultと呼ばれる拡張メソッドを定義:

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

関連する問題