views:

417

answers:

3

Hi fellow coders,

I have a question that's not really a problem, but something that made me a little curious.

I have a class with two methods in it. One is a static method and the other one is an instance method. The methods have the same name.

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

When I try to build my project I get an error saying:

The call is ambiguous between the following methods or properties: 'MyApp.BlockHeader.Peek(System.IO.BinaryReader)' and 'MyApp.BlockHeader.Peek(System.IO.BinaryReader)'

I know that the method signatures are virtually the same, but I can't see how I possibly could call a static method directly from an instance member.

I assume that there is a very good reason for this, but does anyone know what that reason is?

+8  A: 

The general policy of the C# design is to force you to specify wherever there is potential ambiguity. In the face of refactoring tools that allow one to rejig whether things are static or not at the drop of a hat, this stance is great - especially for cases like this. You'll see many other cases like this (override vs virtual, new for shadowing etc.).

In general, removing this type of room for confusion will make the code clearer and forces you to keep your house in order.

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

Ruben Bartelink
The classic example (in this case) being an instance method that calls Peek(...); is that this.Peek? or BlockHeader.Peek?
Marc Gravell
I see your point.
Patrik
1k, well done, you can buy me pint some evening
Binary Worrier
+2  A: 

I think there's no technical reason to disallow it, but it is done more so to protect the programmer from himself. Consider the following example:

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

The example above is perfectly valid, but if the situation you describe were allowed, would it be readable? Could you see, in the blink of an eye, whether the instance method or the static method was called?

Razzie
I see your point. Great example.
Patrik
+4  A: 

Here's a excerpt from the C# 3.0 language specification.

The signature of a method must be unique in the class in which the method is declared. The signature of a method consists of the name of the method, the number of type parameters and the number, modifiers, and types of its parameters. The signature of a method does not include the return type.

The 'static' modifier is not part of the signature so your example violates this rule of unique signatures.

I don't know the reason behind the rule, though.

Vizu