On Instance and Static Method Signatures 

We talked today, with Miha, a C# Yoda. Via IM, everything seemed pointless. Couldn't find a good case for the cause of the following mind experiment:

using System;
class Tubo
  public static void Test() {}
  private void Test() {} 

Note: I'm using Miha's syntax in this post.

We have a static method called Test and an instance method, also called Test. Parameter models of both methods are the same, empty.

Would this compile?

It does not.

The question is why and who/what causes this. There is actually no rationale behind not allowing this thing to compile since both, the compiler and the runtime know the method info upfront.

Since the runtime has all the information it needs, it is strange that this would not be allowed at compile time. However, a (C#) compiler has to determine whether you, the programmer meant to access a static or an instance method.

Here lie the dragons.

It is illegal in most virtual machine based languages to have the same method name and signature for a static/instance method.

The following is an excerpt from a Java specification:

8.4.2 Method Signature

Two methods have the same signature if they have the same name and argument types.

Two method or constructor declarations M and N have the same argument types if all of the following conditions hold:

  • They have the same number of formal parameters (possibly zero)
  • They have the same number of type parameters (possibly zero)
  • Let <A1,...,An> be the formal type parameters of M and let <B1,...,Bn> be the formal type parameters of N. After renaming each occurrence of a Bi in N's type to Ai the bounds of corresponding type variables and the argument types of M and N are the same.

Java (and also C#) does not allow two methods with the same name and parameter model no matter what the access modifier is (public, private, internal, protected ...) and whether the method is static or instance based.


Simple. Programmer ambiguity. There is no technical reason not to allow it.

Consider the following:

using System;
class Tubo
  public static void Test();
  private void Test();
  public void AmbiguousCaller() { Test(); }

What would method AmbiguousCaller call? A static Test or instance Test method?

Can't decide?

That's why this is not allowed.

And yes, it would call the instance method if this would be allowed, since statics in C# should be called using a class name, as in Test.Test(). Note that the preceding example does not compile. Also note, that it is legal to have a AmbiguousCaller body as Test() or Tubo.Test().

There is another ambiguous reason. Local variables in C# cannot be named the same as the enclosing class. Therefore, this is illegal:

using System;
class Tubo
  private int Tubo;

It is. Do a csc /t:library on it.

Since you confirmed this fact, consider the following:

using System;
public class Tubo
  public static void StaticMethod() {}
  public void InstanceMethod() {}

public class RunMe
  public static void Main()
    Tubo Tubo = new Tubo();

Focus on the Main method body. In Tubo.InstanceMethod() an instance method is called and a reference (namely Tubo) is used. In Tubo.StaticMethod() a static method is called and Tubo is not an instance reference, but class name.

It all comes down to programmer ambiguity. Given a chance, I would support this design decision too.

Categories:  CLR
Saturday, November 3, 2007 10:04:38 PM (Central Europe Standard Time, UTC+01:00)  #    Comments


Sunday, November 4, 2007 4:10:59 PM (Central Europe Standard Time, UTC+01:00)
And then you have all sorts of ambiguites introduced with generics as well. Eric Lippert wrote about it a while ago:
Sunday, November 4, 2007 8:11:29 PM (Central Europe Standard Time, UTC+01:00)
Indeed. Let's consider the ambiguities in terms of levels. There are ambiguities and 'ambiguities'. Eric's post talks about real ambiguities which are present in generics, are strongly nonintuitive, but still specified quite well in of the C# spec: http://en.csharp-online.net/ECMA-334:_14.4.2.2_Better_function_member.

Since the spec only talks about generic vs. non-generic implementation and the compiler's preferences if one wants both, one could argue that the limiting cases were chosen against the higher ambiguity, again.
All comments require the approval of the site owner before being displayed.
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Live Comment Preview
Copyright © 2003-2024 , Matevž Gačnik
Recent Posts
RSS: Atom:

The opinions expressed herein are my own personal opinions and do not represent my company's view in any way.

My views often change.

This blog is just a collection of bytes.

Copyright © 2003-2024
Matevž Gačnik

Send mail to the author(s) E-mail