2009-03-01 26 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非常相似。当然,如果你声明一个接口一个字符串索引器,那么你的阅读器代码可以直接使用它 - 但它会是一个不必要的工作来重复实现这个接口!

Re扩展方法;这是否使用常规反射?你可能想看看如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)

+0

有趣的感谢,我会看看。 – judek 2009-03-01 15:58:42

-1

为了重新保湿Pocos,我建议看看AutoMapper Nuget包。它非常简单,大大减少了代码量。