Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关于C语言中不明确调用的问题#_C#_.net_Ambiguous Call - Fatal编程技术网

C# 关于C语言中不明确调用的问题#

C# 关于C语言中不明确调用的问题#,c#,.net,ambiguous-call,C#,.net,Ambiguous Call,我有一个问题其实不是什么问题,但我有点好奇 我有一个包含两个方法的类。一个是静态方法,另一个是实例方法。这些方法具有相同的名称 public class BlockHeader { public static BlockHeader Peek(BinaryReader reader) { // Create a block header and peek at it. BlockHeader blockHeader = new

我有一个问题其实不是什么问题,但我有点好奇

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

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

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


我认为这有一个很好的理由,但是有人知道这个理由是什么吗?

C#design的一般策略是强迫您指定任何可能存在歧义的地方。在重构工具允许人们一下子重新调整事物是否是静态的情况下,这种立场是非常好的——特别是对于这样的情况。您将看到许多其他类似的情况(覆盖vs虚拟、新阴影等)

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


编辑:

我认为没有技术上的理由不允许它,但这样做更多的是为了保护程序员免受自己的伤害。考虑下面的例子:

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

上面的例子是完全正确的,但是如果你描述的情况是允许的,那么它可读吗?你能一眨眼就看出是调用了实例方法还是静态方法吗?

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

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

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


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

我认为这是因为J#和其他语言确实允许您从实例成员调用静态方法。CLR必须强制执行最低公分母。我也觉得这很奇怪。规范非常清楚地表明这种行为是正确的。请参阅第7.5.5.1节,其中的位是:“如果最佳方法是静态方法,则方法组必须由简单名称或通过类型的成员访问产生…”请注意,该位是如何发生在我们计算“最佳”方法的位之后的。在检查静力学之前,首先明确计算“最佳”值。因此,bestness不考虑静态性,在您的情况下,无法确定最佳方法。因此,歧义错误。无论如何,你问的原因。这种奇怪行为的原因是为了解决我们所谓的“颜色问题”。当您使用“Color Color=Color.Red;Color.Foo();”时,这是指“在类型Color上调用静态方法Foo”,还是指“在本地颜色上调用实例方法Foo”?编译器两者都允许,因此在解析Foo之前,无法确定“Color.Foo()”中“Color”的含义。这意味着,在我们确切知道“颜色”的含义之前,必须先解析Foo。在您的情况下,它无法得到明确的解决。有关颜色问题的更多信息,请参阅第7.5.4.1节。Eric Lippert:您应该将您所写的内容复制到答案中,以便我可以将其设置为可接受的答案。经典示例(在本例中)是调用Peek(…)的实例方法;是这个吗,皮克?或者是块头,偷看?