2009-05-07 10 views
13

Hay bastantes preguntas & respuestas sobre la piratería en torno a la limitación de C# que no permite tipos de retorno de método (y argumento) a tipos compatibles en sustituciones, pero ¿por qué existe esta limitación, ya sea en el compilador C# o en el CLR? Como veo, no hay nada que pueda romperse si se permite co/contra-varianza, entonces, ¿cuál es el razonamiento detrás de esto?¿Por qué C#/CLR no es compatible con el método de anulación co/contra-varianza?

Una pregunta similar se podría pedir a ampliar los parámetros de acceso - por ejemplo, sustituir un método interno protegido con un método público (algo que es compatible con Java, IIRC)

+0

¿Por qué votar para cerrar? –

Respuesta

-1

lo hace, sólo hay que esperar a que VS2010/.Net 4.0.

+0

Sin embargo, este es solo el caso de las interfaces, no de los tipos concretos – JaredPar

+0

¿Pero cuál fue el motivo para dejarlo fuera? Parece una cosa muy útil tener, por ejemplo, para el patrón de fábrica – thecoop

+1

@JaredPar - interfaces + delegados ;-p –

-1

Para ampliar la respuesta de Joel, el CLR ha soportado una varianza limitada durante mucho tiempo, pero el compilador de C# no los usa hasta 4.0 con los nuevos modificadores "in" y "out" en interfaces y delegados genéricos. Las razones son complicadas, y me metería en un lío tratando de explicarlo, pero no es tan simple como parece.

Re convirtiendo un método "interno protegido" en un método "público"; usted puede hacer esto con el método de ocultación:

public new void Foo(...) { base.Foo(...); } 

(siempre que los argumentos etc son todos también público) - cualquier uso?

+0

Sí, CLR 2 admite la varianza de tipo genérico. Pero no admitía la covarianza del tipo de devolución. –

+0

La ocultación de métodos funcionaría, pero no actuaría como un método virtual: una llamada a una instancia del supertipo no se enviaría al público. Anular – thecoop

+0

De hecho; tiene limitaciones ... y como no puede anular y "actualizar" la misma firma del mismo tipo, no puede lograr una virtualización adecuada a menos que introduzca un tipo * extra * y una llamada virtual * extra *. –

3

Eric Lippert ya respondió de esta manera mejor que yo.

salir antes de su serie sobre Covariance and Contravariance in C#

y

How does C# 4.0 Generic Covariance & Contra-variance Implmeneted?

EDIT: Eric señaló que él no habla de tipo de retorno convariance pero decidió mantener el enlace en esta respuesta porque es una serie genial de artículos y alguien puede encontrarlo útil si busca este tema.

Esta característica ha sido requested y hace casi 5 años Microsoft ha respondido con "Gracias por registrar esto. Escuchamos esta solicitud mucho. Lo consideraremos para la próxima versión".

Y ahora citaré a Jon Skeet porque no sería una respuesta correcta en StackOverflow sin una respuesta de Jon Skeet. Covariance and void return types

tengo la fuerte sospecha de que la respuesta radica en la aplicación de la CLR más que en cualquier profundidad semántica razón - el CLR probablemente necesita saber si hay o no va a ser un valor de retorno, para hacer cosas apropiadas con la pila. Aún así, parece un poco una pena, en términos de elegancia. No puedo decir que he sentido alguna vez la necesidad de este en bienes vida, y sería razonablemente fácil de falsificar (para hasta cuatro parámetros) en .NET 3.5 con sólo escribir un convertidor de Func<X> a Action<X>, Func<X,Y> a Action<X,Y> etc.Se Niggles un poco aunque :)

+0

Sé que implmenedted se deletrea mal. Pero acabo de vincularlo directamente. –

+5

No, nunca he respondido esta pregunta. Esos artículos tratan sobre la varianza de tipo genérico. Esta pregunta es sobre la covarianza del tipo de retorno. En mis artículos sobre varianza genérica, explícitamente digo que NO estoy hablando de la varianza del tipo de retorno. –

+0

doh. Mi memoria fallida Los leí hace meses y no los volví a leer antes de publicar esta respuesta. :) –

0

costuras introduciendo covarianza de valor de retorno no tiene desventaja esencial como Java y C++ han utilizado. Sin embargo, existe una confusión real al presentar contra-varianza del parámetro formal. Creo que esta respuesta https://stackoverflow.com/a/3010614/1443505 en C++ también es válida para C#.

Cuestiones relacionadas