C# 扩展方法未按预期工作 - 请参阅示例
我想知道 C# 中扩展方法的行为。请参阅下面的示例:
static string ExtendedToString( this object oObj )
{
return "Object";
}
static string ExtendedToString( this Array oArray )
{
return "Array";
}
// Example 1: int array - working as expected.
int[] o = new int[] { 1, 2, 3 };
o.ExtendedToString( ); // returns "Array"
// Example 2: array as object - did not expect the result.
object o = new int[] { 1, 2, 3 };
o.ExtendedToString( ); // returns "Object"
为什么(在最后一种情况下)调用对象的扩展方法而不是 int[] 的扩展方法?
I'm wondering about the behavior of extension methods in C#. Please see the examples below:
static string ExtendedToString( this object oObj )
{
return "Object";
}
static string ExtendedToString( this Array oArray )
{
return "Array";
}
// Example 1: int array - working as expected.
int[] o = new int[] { 1, 2, 3 };
o.ExtendedToString( ); // returns "Array"
// Example 2: array as object - did not expect the result.
object o = new int[] { 1, 2, 3 };
o.ExtendedToString( ); // returns "Object"
Why is (in the last case) the object's extension method called and not the one for int[]?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
重载解析是在编译时执行的。编译器发现
o
被声明为object
,因此它调用采用object
的重载。o
在运行时实际上包含一个数组这一事实是无关紧要的,因为编译器不知道它。这实际上不是特定于扩展方法的,通过将其作为普通静态方法调用(
ExtensionsClass.ExtendedToString(o)
),您将获得相同的结果Overload resolution is performed at compile time. The compiler sees that
o
is declared asobject
, so it calls the overload that takes anobject
. The fact thato
actually contains an array at runtime is irrelevant, because the compiler doesn't know it.That's actually not specific to extension methods, you would get the same result by calling it as a normal static method (
ExtensionsClass.ExtendedToString(o)
)您将 o 声明为对象:
这就是原因:
但是您可以,
因为分辨率取决于(静态)类型
You declared o as object:
thats why:
but you can
as the resolution is depending on the (static) type
因为静态类型。扩展方法由编译器重写,就像您通过常规语法调用它们一样。在编译时,第二个对象 o 具有 Object 类型,因此调用对象的扩展方法
Because of static typing. Extension methods are rewrited by compiler as if you called them by regular syntax. At the compile time, second object o has the type of Object, so object's extension method is called
Thomas Levesque 已经对为什么你的代码不起作用有一个完美的解释,所以我不会重复。解决方法是在运行时使用
is
或as
进行测试:通常,以这种方式进行类型测试有点反模式,并且您应该尽可能选择虚拟方法。但在这种情况下,它可能仍然是最好的解决方案,因为您无法更改数组/对象类。
如果有许多类需要特殊处理,您可以考虑
Type
->Func
字典。Thomas Levesque already has a perfect explanation of why your code doesn't work, so I won't repeat that. The work around is testing at runtime with
is
oras
:Generally type testing in such a way is a bit of an anti-pattern and you should prefer virtual methods where possible. But in this case it's probably still the best solution since you can't change the Array/Object classes.
If there are many classes which need special treatment you could consider a
Type
->Func<object,string>
Dictionary.