我想知道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 []?
答案 0 :(得分:9)
重载分辨率在编译时执行。编译器看到o
被声明为object
,因此它调用带有object
的重载。 o
实际上在运行时包含数组的事实是无关紧要的,因为编译器不知道它。
这实际上并不特定于扩展方法,通过将其称为普通静态方法(ExtensionsClass.ExtendedToString(o)
)来获得相同的结果
答案 1 :(得分:1)
您将o声明为对象:
object o = new int[] { 1, 2, 3 };
这就是为什么:
o.ExtendedToString( ); // returns "Object"
但你可以
int[] obj = o as int[];
obj.ExtendedToString( ); // returns "Array"
因为分辨率取决于(静态)类型
答案 2 :(得分:1)
由于静态输入。扩展方法由编译器重写,就像您通过常规语法调用它们一样。在编译时,第二个对象o具有Object类型,因此对象的扩展方法称为
答案 3 :(得分:0)
托马斯·莱维斯克已经对你的代码无效的原因有了完美的解释,所以我不再重复了。解决方法是在运行时使用is
或as
:
static string ExtendedToString( this object oObj )
{
if(oObj is Array)
return "Array";
else
return "Object";
}
通常,以这种方式进行类型测试有点反模式,您应该尽可能选择虚方法。但在这种情况下,它可能仍然是最佳解决方案,因为您无法更改Array / Object类。
如果有许多课程需要特殊处理,您可以考虑Type
- &gt; Func<object,string>
字典。