C# compiler bug? Why doesn#39;t this implicit user-defined conversion compile?(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#编译器错误?为什么这个隐式用户定义的转换不能编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:C#编译器错误?为什么这个隐式用户定义的转换不能编译?
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- WebMatrix WebSecurity PasswordSalt 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- C#MongoDB使用Builders查找派生对象 2022-09-04
- 输入按键事件处理程序 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- 如何用自己压缩一个 IEnumerable 2022-01-01
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
- C# 中多线程网络服务器的模式 2022-01-01