关于以下编译器错误:
用户定义的运算符&Foo.implicit运算符Foo(Bar)'必须声明为静态和公共
这是什么原因?为什么用户定义的转换运算符必须为public
?
提供以下代码,为什么这种转换不合法:
internal class Bar{}
internal class Foo
{
private Bar _myBar;
internal static implicit operator Bar(Foo foo)
{
return foo._myBar;
}
}
我检查了C# Language Spec,相关部分(10.10.3)没有提到这个要求。它是编译器而不是C#/ .Net限制吗?
为了让事情变得更奇怪,只要public
和Foo
都是Bar
,我就可以制作上面的转换运算符internal
,这很奇怪,因为我会想您无法在公共方法上返回internal
对象(尽管我认为如果整个类都是internal
则不重要)。但是,如果我创建public
PublicFoo
并保留Bar
internal
,那么我会收到inconsistent accessibility
编译错误:
internal class Bar { }
internal class Foo
{
private Bar _myBar;
/// <summary>
/// No inconsistent accessibility: return type
/// </summary>
public static implicit operator Bar(Foo foo)
{
return foo._myBar;
}
}
public class PublicFoo
{
private Bar _myBar;
/// <summary>
/// Inconsistent accessibility: return type !!
/// </summary>
public static implicit operator Bar(PublicFoo foo)
{
return foo._myBar;
}
}
摘要
为什么用户定义的转化必须公开?
答案 0 :(得分:4)
是在§10.10中指定:
以下规则适用于所有运营商声明:
- 操作员声明必须同时包含
public
和static
修饰符。
您没有在第一个代码段中出现“不一致的辅助功能”错误的原因与您在内部类型上定义公共方法时没有出现错误的原因相同。在内部类型上声明公共方法是完全有效的。
在第二个代码段中出现错误的原因是因为 有效,无法在公共类型的公共方法中返回内部类型。这些规则适用于任何方法,而不仅仅是运营商。
至于为什么语言设计师选择要求转换运算符公开...我想他们可能想避免对那些运算符进行过多的“魔术” - 也就是说,他们不希望代码以单向运行在一个组件内部和一个完全不同的方式在另一个组件内,没有任何明显的迹象表明发生了什么。记住操作符只是语法糖。如果您想要一个仅在装配中可见的转换方法,只需定义ToBar()
并自行调用;不要依赖经营者。