Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't a static and non-static method share the same signature?

C# provides following signature characteristics to be used while function overloading.

We know that for overloading takes into consideration only arguments; their number and types, but the objective of polymorphism is to provide same name but different usage depending upon calling strategy.

If I have a class containing two methods with the same name and signature, while one is static and another is not, C# compiler throws an error; "Class already defines a member called 'foo' with the same parameter types".​The call to both the methods are going to be different; one with the object name and the static one with a class name. Hence there is no ambiguity with calling strategy. Then why does it throw an error?

 class Example {

    public void foo() { }
    public static void foo() { }

}

class Program
{
    static void Main(string[] args)
    {

        Example e = new Example();
        e.foo(); 

    }
}
like image 380
Yogesh lele Avatar asked Sep 10 '14 06:09

Yogesh lele


People also ask

Can static and non static method have same name?

A static and non static method can't have the same signature in the same class . This is because you can access both a static and non static method using a reference and the compiler will not be able to decide whether you mean to call the static method or the non static method.

Can a static and instance method have same name?

You can have static and instance method with the same name, as long as their declaration differs in the number or type of parameters. It's the same rule on how you can have two instance methods with the same name in a class.

Why can't we call non static method from static method?

A non-static method is dependent on the object. It is recognized by the program once the object is created. But a static method can be called before the object creation. Hence you cannot make the reference.

Is static part of method signature?

static keywordIt's also part of the method declaration, and we already know its meaning.


2 Answers

Reason why it is throwing an error is that static methods can be called from non-static methods without specifying type name. In this case, compiler won't be able to determine, which method is being called.

public class Foo()
{
   public static void MyMethod() {};
   public void MyMethod() {}

   public void SomeOtherMethod()
   {
      MyMethod(); // which method we're calling static or non-static ?
   }
}

EDIT

Just found this SO post regarding your case. You might want to check it also.

like image 169
Michael Avatar answered Sep 17 '22 22:09

Michael


This error occurs because this is how the behavior is defined in the C# Language Specification. Any "ambiguous" usage (or ways to disambiguate such) is irrelevant, although such reasoning and edge-cases may have led the designers to not explicitly allow such a differentiation .. or it might simply be a C# codification of an underlying .NET CLI/CLR restriction1.

From "3.6 Signatures and overloading" in the C# specification (and in agreement with the linked documentation), formatted as bullets:

The signature of a method consists of

  • the name of the method,
  • the number of type parameters, and
  • the type and kind (value, reference, or output) of each of its formal parameters ..

Method modifiers, including static, are not considered as part of the method signature here.

And, from "1.6.6 Methods" we have the restriction and an agreeing summary:

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

This restriction applies before (and independently of) the method being considered for polymorphism.

Also, as a closing note: instance methods must be virtual or accessed through an interface to be run-time polymorphic in C#. (Both method hiding and method overloading are arguably a form of compile-time polymorphism, but that's another topic..)


1There is support for this simply being the result of a restriction of the .NET CLI/CLR itself that is not worth bypassing (ie. for interoperability reasons). From "I.8.6.1.5 Method signatures" in ECMA-335:

A method signature is composed of

  • a calling convention [CLS Rule 15: "the only calling convention supported by the CLS is the standard managed calling convention"],
  • the number of generic parameters, if the method is generic,
  • [omitted rule]
  • a list of zero or more parameter signatures—one for each parameter of the method— and,
  • a type signature for the result value, if one is produced.

Method signatures are declared by method definitions. Only one constraint can be added to a method signature in addition to those of parameter signatures [CLS Rule 15: "The vararg constraint is not part of the CLS"]:

  • The vararg constraint can be included to indicate that all arguments past this point are optional. When it appears, the calling convention shall be one that supports variable argument lists.

The intersection between the C#/CLS and ECMA signature components is thus the method name, "the number of generic parameters", and "a list of zero or more parameter signatures".

like image 27
user2864740 Avatar answered Sep 19 '22 22:09

user2864740