索引器的扩展方法,它们会好吗?
我正在玩一些能够重新补充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
答案 0 :(得分:11)
索引器与属性共享许多共性(在引擎盖下,索引器是具有索引的属性),并且扩展属性不存在。同意,有些情况下它们很方便。
重新呈现的场景 - 在某些方面,这非常像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)
答案 1 :(得分:-1)
为了补充Pocos,我建议你看一下AutoMapper Nuget包。它非常简单,大大减少了代码量。