24

索引器的扩展方法,它们会好吗?

我正在玩一些重新水合 POCO 的代码。

代码围绕从 SqlDataReader 返回的行进行迭代,并使用反射从列值中分配属性。在我的调用堆栈中,我有一个这样的代码:-

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

Set 方法被编写为扩展方法。

能写出这样的代码就好了

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

即我想为索引器写一个扩展方法

.Net 没有索引器的扩展方法有充分的理由吗?其他人对扩展方法索引器有其他好的用途吗?

顺便说一句……如果我们可以为索引器编写扩展方法,那么我们可以编写这样的代码……</p>

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
4

2 回答 2

12

索引器与属性有很多共同点(实际上,索引器具有索引的属性),并且不存在扩展属性。同意,在某些情况下它们很方便。

重新呈现的场景 - 在某些方面,这很像dynamic。当然,如果你声明一个带有字符串索引器的接口那么你的阅读器代码可以直接使用它——但是重复实现这个接口将是很多不必要的工作!

重新扩展方法;这使用常规反射吗?你可能想看看像这样的技巧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也可用于读取数据(我在 usenet 的某处有一个完整的示例,用于 DbLinq)

于 2009-03-01T15:50:44.610 回答
-1

为了给 Pocos 补水,我建议看一下 AutoMapper Nuget 包。它使得非常简单并且大大减少了代码量。

于 2017-12-20T14:05:19.797 回答