扩展方法适用于索引器,这样做有好处吗?

24

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

我正在尝试一些重新生成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
2个回答

12
索引器与属性有很多共同点(在底层,索引器是带有索引的属性),而扩展属性并不存在。当然,它们会很方便的场景。对于所提出的情况-在某些方面,这就像动态。当然,如果您声明了一个具有字符串索引器的接口,则您的读取器代码可以直接使用它-但是重复实现此接口将是大量不必要的工作!关于扩展方法;这是否使用常规反射?您可能需要查看类似于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示例)。

有趣,谢谢,我会看一下。 - judek

-1

如果要重新激活 Pocos,我建议查看 AutoMapper Nuget 包。它使得操作变得非常简单,并大大减少了代码量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接