Generic Method Substitutions and Unification - Part two

Last time we talked about generic method substitutions which resulted in types being declared with more than one method with identical constructed signatures. After thinking long and hard about this problem, we've come to a conclusion as to how to resolve this issue in the next release.

First, lets recap what we know about the problem.

  1. We currently produce code which causes the CLR to throw TypeLoadExceptions at runtime.
  2. Code that falls into this scenario can be easily fixed by a simple rename
  3. It is a corner case - typical coding practices will not get you into this scenario
  4. The code written is not CLS-compliant

The following is a general set of categories that can result in this scenario occurring:

 // Same class
class Base<T>
{
    void Foo(T t);
    void Foo(int t);
}
 
class C : Base<int> { }
 
// Inherited from base class
class A
{
    void Foo(int i) { }
}
 
class B<T> : A
{
    void Foo(T t) { }
}
 
class C : B<int> { }
 
// Outer class
class A<T>
{
    private void Foo(T t) { }
    private void Foo(int i) { }
 
    class C : A<int> { }
}
 
// Outer class and its base class
class A<T>
{
    public void Foo(T t) { }
}
 
class B<T> : A<T>
{
    private void Foo(int i) { }
    class C : B<int> { }
}

Given the above points, we've decided to take the following action:

  1. If the user specifies that the type is CLS-compliant (via the CLSCompliantAttribute attribute), the compiler will produce a warning indicating that the constructed type is not CLS-compliant
  2. If the user does not specify CLS compliance, or specifies that the type is not CLS-compliant, then we will keep our current behavior, allow the type to be emitted, and produce an assembly that will throw a runtime exception.

This behavior will make it into the next release of the compiler. Until then, don't write code like this if you want it to work! Stay tuned for my investigations on the C# Compiler and modopts!