2016-08-13 11 views
0

にジェネリックのIEnumerable を変換し、私は明示的に CountryIdCountryNameを言及する必要があるが、私はそれを避けたいと generic methodを作成しようとしています。 次のコードでのIEnumerable <KeyValuePair>(C#の)

public struct KeyValueStruct 
{ 
    public int Key { get; set; } 
    public string Value { get; set; } 
} 

private static IEnumerable<KeyValueStruct> ConvertPocoToKeyValueList(IEnumerable<CountryPoco> list) 
{ 
    var result = new List<KeyValueStruct>(); 

    if (list != null) 
    { 
     foreach (var item in list) 
     { 
      result.Add(new KeyValueStruct() 
      { 
       Key = item.CountryId, 
       Value = item.CountryName 
      }); 
     } 
    } 

    return result; 
} 

最初のプロパティは常に整数(この例ではCountryId)であり、2番目のプロパティはStringであることがわかります。

私はGenericsを使用して実装しようとしていましたが、これが最良の方法であるかどうかはわかりません。私の提案したコード(動作しません)を参照してください。

private static IEnumerable<KeyValueStruct> ConvertPocoToKeyValueList<T>(T list) 
{ 
    var result = new List<KeyValueStruct>(); 

    if (list != null) 
    { 
     foreach (var item in list) 
     { 
      result.Add(new KeyValueStruct() 
      { 
       Key = item.CountryId, 
       Value = item.CountryName 
      }); 
     } 
    } 

    return result; 
} 

同じ結果を得るための良い考えがある場合は、提案してください。

+1

「KeyValueStruct」とは何ですか? .NET Frameworkから 'KeyValuePair 'を使用していない理由は何ですか? LINQはすべてのことを自明にしています。btw ... 'var result = countries.Select(c => new KeyValuePair (c.CountryId、c.CountryName).ToList();'入力がnullの場合はおそらく...しかし、あなたはそれが起こっていることを防ぐ方が良いかもしれません。 –

+0

@JonSkeet:私はKeyValueStructを逃して質問に追加したことに気付きました。カスタム構造を持つことはパフォーマンス面ではるかに速いため、.NETのデフォルトのKeyValuePairを使用するのではなく、独自の実装を行うことにしました。 'c.CountryId、c.CountryName'をハードコーディングしないようにする方法はありますか? –

+0

Um 'KeyValuePair'は既に構造体です...あなた自身の' KeyValueStruct'型についてもっと速いと思いますか?確かにそれは可変値型です。違いはありますが、正の値ではありません。 –

答えて

2

キーと値として使用するプロパティを渡すことで、その汎用を行うことができます。私はKeyValuePair<Tkey, TValue>という名前の汎用structを使用して、ホイールを自分で再発明よりも優れていると思う:

private static IEnumerable<KeyValuePair<Tkey, TValue>> 
         ConvertPocoToKeyValueList<TSource, Tkey, TValue> 
            (IEnumerable<TSource> list, 
            Func<TSource, Tkey> keySelector, 
            Func<TSource, TValue> valueSelector) 
     { 
      return list.Select(item => new KeyValuePair<Tkey, TValue> 
              (keySelector(item), valueSelector(item))); 
     } 

使用法:

var result = ConvertPocoToKeyValueList(list, x=> x.CountryId, x=> x.CountryName); 

あなたも、直接使用することで、この一般的な方法を使用しないことを行うことができます。

var result = list.Select(item => new KeyValuePair<Tkey, TValue> 
               (item.CountryId, item.CountryName)); 
+1

'foreach'を持つ必要はなく、ちょっとだけLinq' Select'を使うだけです。 – DavidG

+0

'TKey'と' TValue'型の必要もなく、 'KeyValueStruct'の構造をすでに知っています – DavidG

+0

@DavidGジェネリックを作成せずに自分が望むものを作るために' Select'を使うことができるので、メソッドで、別の汎用メソッドのみを呼び出します。 – user3185569

関連する問題