使用索引器作为方法的参数签名/合同/类型

G. *_*nev 4 c# indexer

作为一个例子,我将使用SqlDataReader和DataRow类:它们都定义了以下索引器:

public object this[int columnIndex] { get; set; }

用作方法参数类型的最小公分母类型是什么,因此两者(以及实现相同索引器的任何其他类)都可以以相同的方式传递和使用,例如:

void DoSomething(??? indexedObject)
{
   string foo = indexedObject[0].ToString(); 
          // let's ignore the presence of ToString()
          // for the purpose of this question
}
Run Code Online (Sandbox Code Playgroud)

object吗?如果索引对象不是派生出来的话object(我认为这是可能的,即使非常不可能).

如果重要,我的目标是.NET 3.5.

编辑:我正在寻找一些合同执行,导致调用者传递实现所述索引器的对象.

Ree*_*sey 7

它是对象吗?

差不多.没有可以使用的通用接口或类,因此object实际上是唯一保证在层次结构中共享的东西.

如果索引对象不是从对象派生的,该怎么办?

这在.NET中是不可能的. System.Object是所有类型的基本类型,并且值始终可以被视为对象(即使它们需要装箱才能使其工作).

但是,object除了通过反射之外,传入不会提供对索引器的访问.

执行此操作的唯一直接方法是via dynamic,但这需要.NET 4(并且不是类型安全的,这意味着您可以获得运行时异常).

更好的方法可能是提供一个Func<T, int, string>允许您在呼叫站点指定如何提取值的方法:

void DoSomething<T>(T object, Func<T, int, string> valueExtractor)
{
    string foo = valueExtractor(object, 0); 
}
Run Code Online (Sandbox Code Playgroud)

然后致电:

DoSomething(indexedObject, (o,i) => o[i].ToString());
Run Code Online (Sandbox Code Playgroud)

这允许您传入一个对象和一种机制来提取给定调用站点索引的值,该值适用于任何类型.


编辑方面:

编辑:我正在寻找一些合同执行,导致调用者传递实现所述索引器的对象.

这些类型都没有实现的内置契约或接口,也没有任何基于索引器存在来约束泛型的方法.您将需要一种不同的方法,例如我建议使用委托来提取值.