如何调用动态类型的扩展方法?

24

我正在阅读Jon Skeet的《C#深度剖析,第二版》。他说我们可以使用两种方法来调用具有动态参数的扩展方法,就像这样:

dynamic size = 5;
var numbers = Enumerable.Range(10, 10);
var error = numbers.Take(size);
var workaround1 = numbers.Take((int) size);
var workaround2 = Enumerable.Take(numbers, size);

然后他说:“如果你想使用动态值作为隐式的this值来调用扩展方法,那么这两种方法都可以使用”。我不知道该怎么做。

非常感谢。


14
现在这不就是最好的办法吗?你读了Jon Skeet的书,现在对于一些你不太清楚的问题,你可以直接从他那里得到答案。 - Cody Gray
2个回答

45

像这样:

dynamic numbers = Enumerable.Range(10, 10);
var firstFive = Enumerable.Take(numbers, 5);

换句话说,只需将其视为静态方法而不是扩展方法进行调用。

或者,如果你知道一个合适的类型参数,你可以通过强制转换来实现,我通常会使用额外的变量:

dynamic numbers = Enumerable.Range(10, 10);
var sequence = (IEnumerable<int>) numbers;
var firstFive = sequence.Take(5);

...但如果您处理的是动态类型,那么您可能不知道序列元素类型,此时第一种版本会让“执行时间编译器”来推断它,基本上是这样。


1
你可以这样做:((IEnumerable<int>)numbers).Take(5)。 - Massif

3

扩展方法只是一种语法糖,它会被C#编译器转换为普通的方法调用。这种转换取决于当前的语法上下文(使用语句导入了哪些命名空间)。

动态变量由运行时处理。此时,CLR无法获得足够的语法上下文信息来决定使用哪个扩展方法。因此,它不起作用。


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