为什么不能在.NET中定义generics索引器?

为什么不能在.NET中创build一个通用索引器?

下面的代码抛出一个编译器错误:

public T this<T>[string key] { get { /* Return generic type T. */ } } 

这是否意味着您不能为通用成员集合创build通用索引器?

我能想到的唯一的东西就是这样:

 var settings = ConfigurationSection.AppSettings; var connectionString = settings<string>["connectionString"]; var timeout = settings<int>["timeout"]; 

但是这实际上并没有给你买任何东西。 你刚刚用尖括号replace了圆括号(如(int)settings [“timeout”]),但没有收到额外的types安全性,你可以自由地做

 var timeout = settings<int>["connectionString"]; 

如果您有强烈的但没有静态types的东西,那么您可能要等到C#4.0及其dynamic关键字。

这是一个有用的地方。 假设你有一个强types的OptionKey<T>来声明选项。

 public static class DefaultOptions { public static OptionKey<bool> SomeBooleanOption { get; } public static OptionKey<int> SomeIntegerOption { get; } } 

哪些选项通过IOptions接口公开:

 public interface IOptions { /* since options have a default value that can be returned if nothing's * been set for the key, it'd be nice to use the property instead of the * pair of methods. */ T this<T>[OptionKey<T> key] { get; set; } T GetOptionValue<T>(OptionKey<T> key); void SetOptionValue<T>(OptionKey<T> key, T value); } 

然后代码可以使用通用索引器作为一个很好的强types选项存储:

 void Foo() { IOptions o = ...; o[DefaultOptions.SomeBooleanOption] = true; int integerValue = o[DefaultOptions.SomeIntegerOption]; } 

在C#2.0 / 3.0中属性不能是通用的,所以你不能拥有一个通用的索引器。

我不知道为什么,但分度器只是语法糖。 写一个通用的方法,而你会得到相同的function。 例如:

  public T GetItem<T>(string key) { /* Return generic type T. */ } 

您可以; 只要从你的声明中删除<T>部分,它会正常工作。 即

 public T this[string key] { get { /* Return generic type T. */ } } 

(假设你的类是一个名字为T的types参数)。

我喜欢有一个索引器的能力,而不用直接引用“索引”项。 我写了一个简单的“callback”索引类下面…

R =从索引器返回的typesP =传入的types到索引器中

所有的索引器真正做的是将操作传递给部署者,并允许他们pipe理实际发生和返回。

 public class GeneralIndexer<R,P> { // Delegates public delegate R gen_get(P parm); public delegate void gen_set(P parm, R value); public delegate P[] key_get(); // Events public event gen_get GetEvent; public event gen_set SetEvent; public event key_get KeyRequest; public R this[P parm] { get { return GetEvent.Invoke(parm); } set { SetEvent.Invoke(parm, value); } } public P[] Keys { get { return KeyRequest.Invoke(); } } } 

要在程序或课堂上使用它:

 private GeneralIndexer<TimeSpan, string> TimeIndex = new GeneralIndexer<TimeSpan,string>(); { TimeIndex.GetEvent += new GeneralIndexer<TimeSpan, string>.gen_get(TimeIndex_GetEvent); TimeIndex.SetEvent += new GeneralIndexer<TimeSpan, string>.gen_set(TimeIndex_SetEvent); TimeIndex.KeyRequest += new GeneralIndexer<TimeSpan, string>.key_get(TimeIndex_KeyRequest); } 

像冠军一样工作,特别是如果您想要监视对列表的访问,或者在访问某些内容时执行任何特殊操作。