C#编译器错误?为什么这个隐式用户定义的转换不能编译? [英] C# compiler bug? Why doesn't this implicit user-defined conversion compile?

查看:17
本文介绍了C#编译器错误?为什么这个隐式用户定义的转换不能编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下结构:

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>
}

但是这段代码不能编译——为什么?

But this code doesn't compile -- why?

private Foo<ICloneable> MakeFoo()
{
    ICloneable c = "hello";
    return c; // Error: ICloneable can't be converted to Foo<ICloneable>. WTH?
}

推荐答案

显然,当其中一种类型是接口时,隐式用户定义转换不起作用.来自 C# 规范:

Apparently, implicit user defined conversions don't work when one of the types is an interface. From the C# specs:

6.4.1 允许的用户定义转换

6.4.1 Permitted user-defined conversions

C# 只允许声明某些用户定义的转换.特别是,不可能重新定义已经存在的隐式或显式转换.对于给定的源类型 S 和目标类型 T,如果 S 或 T 是可空类型,则令 S0 和 T0 引用它们的基础类型,否则 S0 和 T0 分别等于 S 和 T.仅当满足以下所有条件时,才允许类或结构声明从源类型 S 到目标类型 T 的转换:

C# permits only certain user-defined conversions to be declared. In particular, it is not possible to redefine an already existing implicit or explicit conversion. For a given source type S and target type T, if S or T are nullable types, let S0 and T0 refer to their underlying types, otherwise S0 and T0 are equal to S and T respectively. A class or struct is permitted to declare a conversion from a source type S to a target type T only if all of the following are true:

  • S0 和 T0 是不同的类型.
  • S0 或 T0 是发生运算符声明的类或结构类型.
  • S0 和 T0 都不是接口类型.
  • 排除用户定义的转换,不存在从 S 到 T 或从 T 到 S 的转换.

在您的第一种方法中,两种类型都不是接口类型,因此用户定义的隐式转换有效.

In your first method, both types are not interface types, so the user defined implicit conversion works.

规范不是很清楚,但在我看来,如果涉及的类型之一是接口类型,编译器甚至不会尝试查找任何用户定义的隐式转换.

这篇关于C#编译器错误?为什么这个隐式用户定义的转换不能编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆