给定以下结构:
public struct Foo<T>
{
public Foo(T obj) { }
public static implicit operator Foo<T>(T input)
{
return new Foo<T>(input);
}
}
此代码编译:
private Foo<ICloneable> MakeFoo()
{
string c = "hello";
return c; // Success: string is ICloneable, ICloneable implicitly converted to Foo<ICloneable>
}
但这段代码无法编译——为什么?
private Foo<ICloneable> MakeFoo()
{
ICloneable c = "hello";
return c; // Error: ICloneable can't be converted to Foo<ICloneable>. WTH?
}
最佳答案
显然,当其中一种类型是接口(interface)时,隐式用户定义的转换不起作用。来自 C# 规范:
6.4.1 允许的用户定义转换
C# 只允许声明某些用户定义的转换。特别是,不可能重新定义已经存在的隐式或显式转换。 对于给定的源类型 S 和目标类型 T,如果 S 或 T 是可空类型,则让 S0 和 T0 引用它们的基础类型,否则 S0 和 T0 分别等于 S 和 T。仅当满足以下所有条件时,才允许类或结构声明从源类型 S 到目标类型 T 的转换:
- S0 和 T0 是不同的类型。
- S0 或 T0 是发生运算符声明的类或结构类型。
- S0 和 T0 都不是接口(interface)类型。
- 不包括用户定义的转换,不存在从 S 到 T 或从 T 到 S 的转换。
在您的第一个方法中,两种类型都不是接口(interface)类型,因此用户定义的隐式转换有效。
规范不是很清楚,但在我看来,如果涉及的类型之一是接口(interface)类型,编译器甚至不会尝试查找任何用户定义的隐式转换。
关于C# 编译器错误?为什么这个隐式的用户定义转换不能编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1208796/