9

我有一个问题,这不是一个真正的问题,但让我有点好奇。

我有一个类,里面有两种方法。一种是静态方法,另一种是实例方法。这些方法具有相同的名称。

public class BlockHeader
{
    public static BlockHeader Peek(BinaryReader reader)
    {
        // Create a block header and peek at it.           
        BlockHeader blockHeader = new BlockHeader();
        blockHeader.Peek(reader);
        return blockHeader;
    }

    public virtual void Peek(BinaryReader reader)
    {
        // Do magic.
    }
}

当我尝试构建我的项目时,我收到一条错误消息:

以下方法或属性之间的调用不明确:“MyApp.BlockHeader.Peek(System.IO.BinaryReader)”和“MyApp.BlockHeader.Peek(System.IO.BinaryReader)”

我知道方法签名实际上是相同的,但我看不出我怎么可能直接从实例成员调用静态方法。

我认为这是有充分理由的,但有人知道这是什么原因吗?

4

3 回答 3

9

C# 设计的一般策略是强制您指定可能存在歧义的地方。面对允许人们一举两得地重新调整事物是否静态的重构工具,这种立场是很好的——尤其是对于这样的情况。您会看到许多其他类似的情况(覆盖与虚拟,新的阴影等)。

一般来说,消除这种混乱的空间会使代码更清晰,并迫使你保持你的房子井井有条。

编辑:来自 Eric Lippert 的一篇好文章讨论了导致您看到的错误的歧义的另一个原因

于 2009-05-20T09:36:14.790 回答
4

这是 C# 3.0 语言规范的摘录。

方法的签名在声明该方法的类中必须是唯一的。方法的签名由方法的名称、类型参数的数量及其参数的数量、修饰符和类型组成。方法的签名不包括返回类型。

'static' 修饰符不是签名的一部分,因此您的示例违反了此唯一签名规则。

不过,我不知道规则背后的原因。

于 2009-05-20T10:08:00.497 回答
2

我认为没有技术上的理由来禁止它,但这样做更多是为了保护程序员免受自己的伤害。考虑以下示例:

public static void Main()
{
  BlockHeader BlockHeader = new BlockHeader();
  BlockHeader.Peek();
}

上面的例子是完全有效的,但如果你描述的情况是允许的,它是否可读?你能一眼看出是调用了实例方法还是静态方法?

于 2009-05-20T09:47:39.993 回答