2009-03-01 4 views
22

インデクサーの拡張メソッド、彼らは良いでしょうか?インデクサーの拡張メソッド、彼らは良いだろうか?

私はPOCOを再水和するいくつかのコードで遊んでいました。

このコードは、SqlDataReaderから返された行を反復処理し、リフレクションを使用して列の値からプロパティを割り当てます。私のコールスタックの下に私は次のようなコードを持っていました: -

poco.Set("Surname", "Smith"); // uses extension method ... 

Setメソッドは拡張メソッドとして書かれています。

私は、インデクサ

ための拡張メソッドを書きたかったこの

poco["Surname"] = "Smith"; // extension methods for indexers ? 

すなわち.NETは拡張メソッドを持っていない理由はそこに正当な理由はありますようにコードを書くことができたのは素晴らしいことでしょうインデクサーのために? 他の人が、拡張メソッドインデクサーの他の優れた用途を持っていますか?さておき... 私たちはインデクサーのための拡張メソッドを書くことができれば、我々はこのようなコードを書くことができよう

...

var poco = PocoFactory(); 
    poco.Surname = “Smith”; // is this JavaScript ... 
    poco[Surname] = “Smith” ; // … or is this c# or both 

私のコードから一部抜粋が

///////////////////////////////////////////// 
// Client calling code 
IDab dab = DabFactory.Create("Northwind"); 
string sql = @"select * from Customers "; 
var persons = dab.ExecuteReader<NorthwindCustomer>(sql); 
if (dab != null{ 
    Assert.That(persons[0].CustomerID , Is.EqualTo("ALFKI"));} 
///////////////////////////////////////////// 
List<T> IDab.ExecuteReader<T>(string commandText) 
{ 
    List<T> pocos = new List<T>(); 
    // setup connection 
    SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection); 
    while (reader.Read()) 
    { 
      Dictionary<string, int> colMappings = null ; 
      if (colMappings == null){ 
       colMappings = reader.GetSqlDataReaderColumnMappings();} 
      T poco = new T(); 
      poco.DbToMem<T>(reader, colMappings); 
      pocos.Add(poco); 
     } 
    } 
    // connection cleanup ... 
    return pocos ; 
} 

// the set extension method signature 
public static void Set<T>(this T thisClientObject, string thisPropertyName, object newValue) where T : class 

答えて

11

インデクサーは多くのことを共有します(フードの下ではインデクサです)、拡張プロパティは存在しません。合意して、彼らが便利なシナリオがあります。

シナリオはいくつかの点で、dynamicと非常によく似ています。もちろん、という文字列インデクサーがあるインターフェイスを宣言すると、リーダーコードで直接使用することができますが、lotこのインターフェイスを繰り返し実装することになります。

拡張メソッド。これは正反射を使用していますか? HyperDescriptorのようなトリックを見たいと思うかもしれません。これはたくさんのCPU時間を節約することができます。典型的な使い方は次のようになります。

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T)); 
while (reader.Read()) 
{ 
    T poco = new T(); 
    // abbreviated... 
    (per prop) 
     props[propName].SetValue(poco, cellValue); 
} 

あなたは...(一度グリッドごとではなく、行あたりの)最初の返される列を見て、とだけマッチした列にアクセスすることにより、さらに

またはその代わりに、これを最適化することができ、 ORMツールを見てください。 Expressionもデータの読み込みに使用することができます(私はDbLinqのusenetのどこかの完全な例を持っています)

+0

面白いおかげで、私は見ていきます。 – judek

-1

AutoMapper Nugetパッケージを見直すことをお勧めします。それは本当にシンプルであり、コードの量を大幅に削減します。