C# 编译器错误?为什么这个隐式的用户定义转换不能编译?

标签 c# compiler-construction

给定以下结构:

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/

相关文章:

compiler-construction - LLVM是否适合并行语言?

c# - 调用 ASP.NET 用户控件事件时调用页面事件

C# TabControl不会刷新

java - 如何使用 stringtokenizer 构建扫描器

c编译器错误链接

c# - short null 值为什么要转换成 int null 值来和 null 比较?

c++ - 如何获取LLVM全局变量常量值?

c# - 防止访问 mvc 中的操作的最佳方法

c# - 将图像转换为 HEX 纯文本,与存储在 SQL Server 中的内容相同

c# - 如何在 web api 中发送两个对象作为响应消息和响应代码