インデクサーの拡張メソッドは良いでしょうか? [closed] 質問する

インデクサーの拡張メソッドは良いでしょうか? [closed] 質問する

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

私は 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

ベストアンサー1

インデクサーはプロパティと多くの共通点を持っています(内部的には、インデクサーはインデックス付きのプロパティ) があり、拡張プロパティは存在しません。 確かに、拡張プロパティが便利なシナリオはあるでしょう。

提示されたシナリオについて - ある意味では、これは非常に似ていますdynamic。もちろん、もっている文字列インデクサがあれば、リーダーコードで直接使用できますが、多くこのインターフェースを繰り返し実装するのは不必要な作業です。

拡張メソッドについてですが、これは通常のリフレクションを使用していますか?次のようなトリックを検討してみるといいかもしれません。HyperDescriptor、これをたくさん行う場合は、CPU 時間を大幅に節約できる可能性があります。一般的な使用法は次のようになります。

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

返された列を最初に確認し (行ごとではなくグリッドごとに 1 回)、一致した列のみにアクセスすることで、これをさらに最適化できます...

あるいは、ORM ツールを見てください。Expressionデータの読み取りにも使用できます (Usenet のどこかに DbLinq の完全な例があります)

おすすめ記事