【发布时间】:2020-09-30 06:54:10
【问题描述】:
我有以下两个课程:
public class Parent
{
public static Parent operator +(Parent l, Parent r)
{
return new Parent(); //do something meaningful
}
}
public class Child: Parent
{
public static Child operator +(Child l, Parent r)
{
return new Child(); //do something meaningful, child related
}
}
然后我有一个包装类,它使用implicit 转换来返回包装后的值:
public class Wrapper<T>
{
private T value;
public T Value => value;
public static implicit operator T(Wrapper<T> wrapper)
{
return wrapper.value;
}
}
然后我将两者组合如下:
public class Usage
{
private Parent someField;
private Wrapper<Child> wrappedValue;
public void UseOperatorWithImplicitConversion()
{
//Child sum1 = wrappedValue + someField; //<-- compilation error
Parent sum2 = wrappedValue + someField;
Child temp = wrappedValue; //works but defeats the purpose of reduced verbosity
Child sum3 = temp + someField;
}
}
我期待 sum1 线路能够正常工作。我查看了生成的 IL,似乎类型在那里:
IL_0001: ldarg.0 // this
IL_0002: ldfld class Example.Wrapper`1<class Example.Child> Example.Usage::wrappedValue
IL_0007: call !0/*class Example.Child*/ class Example.Wrapper`1<class Example.Child>::op_Implicit(class Example.Wrapper`1<!0/*class Example.Child*/>)
IL_000c: ldarg.0 // this
IL_000d: ldfld class Example.Parent Example.Usage::someField
IL_0012: call class Example.Parent Example.Parent::op_Addition(class Example.Parent, class Example.Parent)
IL_0017: stloc.0 // sum2
虽然IL_0012 是对Parent 的op_Addition 的调用,而不是Child。
这里有什么我遗漏的吗?
我正在使用 .NET Framework 4.6.1 C# 7.2
【问题讨论】:
-
我会说编译器首先选择一个可用的
operator +候选者(参见语言规范的 binary operator overload resolution 部分)并使用它可以工作的第一个。 -
@GuruStron 但我希望如果我从
Parent中删除运算符重载,那么它将编译为第二好的是来自Child的运算符。不是这样的,我仍然得到错误。 -
是的,没错,错过了。
标签: c# generics operator-overloading implicit-conversion overload-resolution