为什么C#中的转换运算符必须声明为静态和公共的?

9

关于以下编译器错误:

用户定义的运算符 'Foo.implicit operator 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的限制吗?

更奇怪的是,只要FooBar都是internal,我就可以把上面的转换操作符声明为public,这很奇怪,因为我认为你不能在公共方法中返回一个internal对象(尽管如果整个类是internal,那无所谓)。然而,如果我创建一个publicPublicFoo并保持Barinternal,那么我会得到一个“不一致的可访问性”编译器错误:

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

摘要

为什么用户定义的转换必须是公共的?

1个回答

6

在第10.10节中指定了以下规则适用于所有运算符声明:

所有运算符声明必须包含一个public和一个static修饰符。

你在第一个片段中没有得到“不一致的可访问性”错误的原因,与你在一般情况下在内部类型上定义公共方法时不会出错的原因相同。在内部类型上声明公共方法是完全有效的。

你在第二个片段中出现错误的原因是因为在公共类型的公共方法中返回内部类型是无效的。这些规则适用于任何方法,而不仅仅是运算符。

至于语言设计者选择要求转换运算符为公共的原因......我想他们可能希望避免在这些运算符中发生太多“魔法”,也就是说,他们不想让代码在一个程序集内以一种方式工作,在另一个程序集内以完全不同的方式工作,而没有明显的指示正在发生什么。请记住,运算符只是语法糖。如果你想拥有一个只能在你自己的程序集中可见的转换方法,只需定义ToBar()并自己调用它;不要依赖运算符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接