Reputation: 12245
Why am I not allowed to have a static and non-static methods with the same signature?
Let's say I have a class like this
public class TestClass
{
public object thing { get; set; }
public TestClass()
{
}
public TestClass(object thing)
{
this.thing = thing;
}
public static TestClass ConvertTestClass(object thing)
{
return new TestClass(thing);
}
public TestClass ConvertTestClass(object thing)
{
this.thing = thing;
return this;
}
}
and I try to use it like this
public class SomeOtherClass
{
public SomeOtherClass()
{
TestClass tc = TestClass.ConvertTestClass(new object());
TestClass tc2 = new TestClass();
tc2.ConvertTestClass(new object());
}
}
I get the following errors on TestClass.ConvertTestClass(new object());
The call is ambiguous between the following methods or properties: 'TestClass.ConvertTestClass(object)' and 'TestClass.ConvertTestClass(object)'
and these errors on tc2.ConvertTestClass(new object());
The call is ambiguous between the following methods or properties: 'TestClass.ConvertTestClass(object)' and 'TestClass.ConvertTestClass(object)'
Member 'TestClass.ConvertTestClass(object)' cannot be accessed with an instance reference; qualify it with a type name instead
Can the compiler really not tell the difference between the static and non static versions of that method or am I missing something here?
I am not using ReSharper (which seemed to be the root of a similar problem in other questions).
Upvotes: 5
Views: 3936
Reputation: 6864
I'd write this as a comment however it's easier to make this point in a proper editor.
I think you're only thinking about the logic of calling methods on the class externally i.e. from another class. Within the class methods with the same signature only differing by static doesn't make any sense. e.g you have a class with two methods as follows
public class MyClass
{
public static void HellowWorld()
{
Console.WriteLine("Hello World!");
}
public void HellowWorld()
{
Console.WriteLine("Howdy World!");
}
public void Greet()
{
HellowWorld();
}
}
When compiling you'll see as long as one of the methods is commented out it compiles without errors. You should be able to alternate the commented out method and compile the class succesfully. Indicating there's no way of differentiating which method should be called within the scope of the class.
You could argue that within the class you should be forced to use the same syntax to call a static method as you do externally e.g.
MyClass.HelloWorld();
However, this would defy scoping logic used throughout C#, why should you need to specify the class name within a class? I think such a change would also create ambiguity where the was none, and to do so now would of course break a lot of code out there.
I think the compiler logic as it is makes perfect sense.
Upvotes: 0
Reputation: 61339
Its giving you an error, so its a safe bet that the compiler can't, or won't, discern between the two methods.
Its probably a bad idea to do this kind of overload anyways, as it's unclear which method you are intending to invoke, but if that isn't enough, the C# 5 specification defines a method signature like this (Section 3.6):
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, considered in the order left to right. For these purposes, any type parameter of the method that occurs in the type of a formal parameter is identified not by its name, but by its ordinal position in the type argument list of the method. The signature of a method specifically does not include the return type, the params modifier that may be specified for the right-most parameter, nor the optional type parameter constraints.
It doesn't explicitly mention static
, but it also doesn't include it as part of the definition of a "signature". Thus, its fair to assume that by the spec, a method overload cannot differ only in the fact that it is static or instanced.
Upvotes: 4