关于索引器和/或generics的问题

如何知道对象是否实现索引器?我需要共享DataRow和IDataReader的逻辑,但它们不共享任何接口。

我也尝试使用generics,但不知道我应该对where子句施加什么限制。

public class Indexer { // myObject should be a DataRow or a IDataReader private object myObject; public object MyObject { get { return myObject; } set { myObject = value; } } // won't compile, myObject has no indexer public object this[int index] { get { return myObject[index]; } set { myObject[index] = value; } } public Indexer(object myObject) { this.myObject = myObject; } } public class Caller { void Call() { DataRow row = null; IDataReader reader = null; var ind1 = new Indexer(row); var ind2 = new Indexer(reader); var val1 = ind1[0]; var val2 = ind1[0]; } } 

您需要声明具有索引器属性的接口,使用该接口作为约束,并且类型参数类需要实现该接口以满足约束。

由于您无法控制要使用的类,因此无效。

另一种方法是使Indexer类将get / set操作作为单独的参数:

 public class Indexer { private Func getter; private Action setter; public object this[int index] { get { return getter(index); } set { setter(index, value); } } public Indexer(Func g, Action s) { getter = g; setter = s; } } public static class IndexerExtensions { public static Indexer ToIndexer(this DataRow row) { return new Indexer(n => row[n], (n, v) => row[n] = v); } public static Indexer ToIndexer(this IDataReader row) { return new Indexer(n => row[n], (n, v) => row[n] = v); } } 

然后你可以这样做:

 DataRow row = null; IDataReader reader = null; var ind1 = row.ToIndexer(); var ind2 = reader.ToIndexer(); var val1 = ind1[0]; var val2 = ind1[0]; 

您可以使Indexer成为一个抽象基类,包含两个子类,一个用于DataRow,另一个用于IDataReader。

为了便于使用,可能存在2种工厂方法,例如:

 var ind1 = Indexer.CreateFromDataRow(row);
 var ind2 = Indexer.CreateFromIDataReader(reader);

他们可以为该类型创建一个特定的基类,它有自己的逻辑来处理索引。

这避免了为每个get / set调用不断检查类型的开销(以单个虚拟属性而不是标准属性为代价)。

 get { DataRow row = myObject as DataRow; if (row != null) return row[index]; IDataReader reader = myObject as IDataReader; if (reader != null) return reader[index]; } 

并为set {}使用相同的逻辑