Su pregunta se discute caliente cuando se está diseñando C# 2.0 y el sistema de tipo genérico en el CLR. ¡Tan ardientemente, de hecho, que la especificación "enlazada" C# 2.0 publicada por A-W en realidad tiene una regla incorrecta! Hay cuatro posibilidades:
1) Declarar ilegal una clase genérica que POSIBLEMENTE podría ser ambigua bajo SOME construction. (Esto es lo que la especificación encuadernada dice incorrectamente es la regla). Por lo tanto, su declaración Foo<T>
sería ilegal.
2) Establezca la ilegalidad de construir una clase genérica de manera que cree una ambigüedad. declarar Foo<T>
sería legal, la construcción de Foo<double>
sería legal, pero la construcción de Foo<int>
sería ilegal.
3) Haga que todo sea legal y use trucos de resolución de sobrecarga para determinar si la versión genérica o no genérica es mejor. (Esto es lo que realmente hace C#.)
4) Haz otra cosa en la que no haya pensado.
La regla n. ° 1 es una mala idea porque hace que algunos escenarios muy comunes e inofensivos sean imposibles.Consideremos por ejemplo:
class C<T>
{
public C(T t) { ... } // construct a C that wraps a T
public C(Stream state) { ... } // construct a C based on some serialized state from disk
}
¿Quieres que para ser ilegal sólo porque C<Stream>
es ambiguo? Yuck. La regla n. ° 1 es una mala idea, así que la descartamos.
Desafortunadamente, no es tan simple como eso. IIRC Las reglas de la CLI dicen que una implementación puede rechazar como construcciones ilegales que en realidad causan ambigüedades de firma. Es decir, las reglas CLI son algo así como la Regla # 2, mientras que C# realmente implementa la Regla # 3. Lo que significa que, en teoría, podría haber programas legales de C# que se traducen en código ilegal, lo que es profundamente desafortunado.
Para algunos pensamientos más sobre cómo este tipo de ambigüedades hacen la vida miserable, aquí hay un par de artículos que escribí sobre el tema:
http://blogs.msdn.com/ericlippert/archive/2006/04/05/569085.aspx
http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx
Supongo que el tercer Foo <> en 2 tiene que ser int – Dykam
"programas legales de C# que se traducen en código ilegal" ¿Cómo es posible? Pensé que la traducción da como resultado una instrucción 'newobj' y un token de método, donde' Foo .ctor (int) 'y' Foo .ctor (T) 'tienen tokens de método diferentes. Entonces no hay ambigüedad en el IL. ¿Me he perdido algo? –
@BenVoigt: Primero, en lugar de "código ilegal" hubiera sido más preciso si hubiera dicho "código no verificable" o "código con comportamiento definido por la implementación". Las consecuencias de una construcción genérica que produce una colisión de firma son sutiles. Supongamos, por ejemplo, que tenemos dos métodos con la misma firma y deseamos indicar en los metadatos que uno de ellos es la implementación de un método de interfaz particular. No hay una construcción de metadatos que pueda ir en la tabla de implementación de métodos que desambigua entre dos métodos con la misma firma. Hay otros casos impares similares. –