kri*_*gar -2 c# generics extension-methods
我终于厌倦了IEnumerable没有Add方法,并决定通过扩展方法添加我自己的方法.我最初的尝试是这样的:
public static void Add(this IEnumerable<T> items, T item)
{
...
}
Run Code Online (Sandbox Code Playgroud)
这引发了关于T未定义的预期编译器错误,因此我将签名更改Add<T>为定义它.(有关解释,请参阅此答案.)
但是,这让我思考.如果我们自己创建一个泛型类(比如IEnumerable<T>),我们可以像我最初尝试的那样添加方法,因为它T是在类中定义的.
我知道扩展方法不是作为类的一部分创建的.编译器中没有"魔术"将它们添加到原始类中.
我仍然认为,由于this初始参数的声明<T>,该参数可以用于定义方法的类型.
我的问题是:
为什么扩展方法存在这种限制?是否有针对此限制的解释?是否可以向语言团队提出并在未来的版本中添加?
更具体地说,Jonsey更有说服力地重申了我的观点:
我想我得到了你所要求的.为什么编译器不够智能,在给定方法签名的情况下,已经声明了T,并且实际上不需要在签名中?
编辑
我应该Add<T>在发布之前使用我的新方法(),因为我发现在使用该方法时,我不必一般地调用它,我可以使用.Add().我想这与这个答案一致.我仍然觉得它必须被宣布的方式很奇怪,也许这会给整个情况带来麻烦.
反对这个问题重复的争论
提到创造IEnumerable<T>.Add()仅仅是为了说明我发现这种"特殊性"背后的推理,我的问题更通用,不是特定于那种方法.
那么,你需要问问自己T这里有什么特别之处.假设我们要写:
public static void Add(this IEnumerable<X> items, X item)
Run Code Online (Sandbox Code Playgroud)
......你希望它能起作用吗?如果是这样,请考虑:
public static void Add(this IEnumerable<Button> items, Button item)
Run Code Online (Sandbox Code Playgroud)
你会想到,意味着同样的事情,即有效地泛型方法服用任何序列,或者实际上只能使意义的IEnumerable<Button>地方Button是System.Windows.Forms.Button类或任何适当的using指令指示?
基本上,编译器需要查找是什么T意思.那可以是:
在您的情况下,您处于非泛型类和非泛型方法中,因此它会回退到正常类型查找失败.
基本上你希望它是一个类型参数,所以它必须是一个泛型方法(或类,但泛型类中不允许使用扩展方法).
如果你不认为第一个例子(与X)应该工作,那么想必你期待T的背景下要查找IEnumerable<>的类型,这使得事情更奇怪,因为这意味着该类型的参数名称从成为重要的"客户端"代码的方式不是语言中的任何其他地方.它还使其他事情变得棘手.例如:
static void Add(this IEnumerable<T> items, Dictionary<T, T> dict)
Run Code Online (Sandbox Code Playgroud)
这T是有效的IEnumerable<T>,但Dictionary<,>有TKey,TValue...所以编译器应该说IEnumerable<T>胜利?它最终被多比只是说更混乱"不行,如果你想有一个通用的方法,你必须声明的类型参数."
| 归档时间: |
|
| 查看次数: |
723 次 |
| 最近记录: |