关于C#中模糊调用的问题

时间:2009-05-20 09:30:53

标签: c# .net ambiguous-call

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

我有一个有两种方法的课程。一个是静态方法,另一个是实例方法。方法具有相同的名称。

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)'

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

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

3 个答案:

答案 0 :(得分:9)

C#设计的一般政策是强制您指定存在潜在歧义的地方。面对重构工具,允许人们在一塌糊涂的情况下重新调整事物是否是静态的,这种立场是很好的 - 特别是对于这样的情况。你会看到很多其他的情况(覆盖与虚拟,新的阴影等)。

一般情况下,删除此类混淆空间会使代码更清晰,并迫使您保持整洁。

编辑:A good post from Eric Lippert discusses another reason for this ambiguity leading to the error you saw

答案 1 :(得分:4)

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

  

方法的签名在声明方法的类中必须是唯一的。方法的签名包括方法的名称,类型参数的数量以及数量,修饰符和参数类型。方法的签名不包括返回类型。

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

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

答案 2 :(得分:2)

我认为没有技术理由不允许它,但更多的是为了保护程序员免受他自己的伤害。请考虑以下示例:

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

上面的示例完全有效,但如果您描述的情况被允许,它是否可读?你能在眨眼之间看到是否调用了实例方法或静态方法吗?