Ruu*_*jah 0 .net c# polymorphism compiler-errors operators
考虑
interface IResult {}
class Result : IResult {}
class Results : IResult {}
class Producer {
private Results results;
IResult DoSomething() {
return results ?? new Result();
}
}
Run Code Online (Sandbox Code Playgroud)
这会因编译器错误而失败
Operator '??' cannot be applied to operands of type `Result` and `Results`
Run Code Online (Sandbox Code Playgroud)
对我来说,这是出乎意料的行为.考虑到这一点,.NET框架可能会创建一个类型的中间变量Results(左操作数).右操作数Result的类型不同,因此会产生类型转换错误.这个假设是否正确?
如果是,为什么csc不会检测到中间变量的类型IResult?
所以我把代码改成了样子
return results == null ? new Result() : results;
Run Code Online (Sandbox Code Playgroud)
但是这段代码错了
There is no explicit conversion between `Result` and `Results`
Run Code Online (Sandbox Code Playgroud)
为什么?我不指望这个,因为两个实例都符合IResult.
因为这:
return results ?? new Result();
Run Code Online (Sandbox Code Playgroud)
实际上它试图将最后一个参数的值转换为与第一个参数相同的类型.编译器认为这是您需要的类型.它不使用您分配给它的变量的类型.
你需要一个隐式演员.把它投到IResult你会很好:
return (IResult)results ?? new Result();
Run Code Online (Sandbox Code Playgroud)
嗯,这是预期的。因为Result和Results是不一样的类,他们只是实现一个共同的接口,但它们无法转换为对方,这就是为什么你所得到的错误。
如果是,为什么 csc 不会检测到 IResult 类型的中间变量?
这会造成歧义。如果您的类型实现了多个通用接口,例如IFoo. 那么编译器应该选择IResult还是IFoo?你可以说它应该IResult因为返回类型而选择,但是应该发生什么这不是一个 return 语句,这可能是简单的赋值,例如.. 简而言之,C#编译器不会对类型做出假设。
这也在声明C# Specification中 7.13 The null coalescing operator
类型表达
a ?? b取决于哪个隐式转换可用偏好operands.In顺序的类型,a ?? bISA0,A或B,其中A是的式a(前提是一个具有类型),B是的类型b(条件是b 有一个类型),如果 A 是可空类型,则 A0 是 A 的基础类型,否则为 A。具体a ?? b处理如下:
[...] 如果
A存在并且存在从bto的隐式转换A,则结果类型为A[...] 如果
b有一个类型B并且存在从ato的隐式转换B,则结果类型为 B。否则,
a并且b是不兼容的,并发生编译时错误。
| 归档时间: |
|
| 查看次数: |
209 次 |
| 最近记录: |