2011-04-28 7 views
10

dado:IEnumerable <IMyInterface> Implícitamente de Class [] pero no de Struct []. ¿Por qué?

public interface IMyInterface{ 

} 

public class MyClass:IMyInterface{ 
    public MyClass(){} 
} 

public struct MyStruct:IMyInterface{ 
    private int _myField; 

    public MyStruct(int myField){_myField = myField;} 
} 

¿Por qué puedo escribir:

IEnumerable<IMyInterface> myClassImps = new[] { 
    new MyClass(), 
    new MyClass(), 
    new MyClass() 
}; 

Pero no:

IEnumerable<IMyInterface> myStructImps = new[]{ 
    new MyStruct(0), 
    new MyStruct(1), 
    new MyStruct(2) 
}; 

Lo que me da la siguiente advertencia:

Error 29 No se puede implícitamente convertir escriba 'MyApp.MyNS.MyStruct []' en 'System.Co llections.Generic.IEnumerable <MyApp.MyNS.IMyInterface> '

Y en lugar debe ser escrito:

IEnumerable<IMyInterface> myStructImps = new IMyInterface[]{ 
    new MyStruct(0), 
    new MyStruct(1), 
    new MyStruct(2) 
}; 

Respuesta

4

El problema es la covarianza de matriz. This specification hablar de ello:

Para cualquier dos tipos de referencia A y B, si existe una conversión implícita de referencia (Sección 6.1.4) o la conversión referencia explícita (Sección 6.2.3) de A a B, entonces el misma conversión de referencia también existe desde el tipo de matriz a [R] para el tipo de matriz B [R], donde R es cualquier rango-especificador dado (pero la misma para ambos tipos de matriz)

Un ejemplo más sencillo de esta que también falla es

int[] c = new int[0]; 
object[] d = c; 

while

string[] c = new string[0]; 
object[] d = c; 

funciona bien. Básicamente estás tratando de hacer lo mismo. Tiene una matriz de tipos de valor MyStruct y está intentando convertirlo implícitamente a IMyInterface, que no está cubierto por la especificación de covarianza de matriz.

+0

La pregunta está etiquetada con C# 3.0, ¿de qué varianza está hablando? –

+0

@Darin Lo siento, citación equivocada –

+0

Entiendo que veo que hay lagunas en mi respuesta, pero la única cosa que no entiendo acerca de esta explicación es que si esto es realmente solo un problema de covarianza, entonces ¿por qué puede instanciar asignar el enumerable con una matriz de 'MyClass', pero no con una matriz de 'MyStruct's'. Esto en particular fue por lo que pensé que esto tiene algo que ver con el boxeo. – LJM

0

Una estructura no es una clase. Existen diferentes reglas al crear instancias de ellos. Sin investigarlo, supongo que el tipo no se puede inferir en su primer ejemplo porque no es una clase. Cuando es explícito, no hay problema.

1

El que funciona realiza un boxeo implícito y luego lo lanza a un IMyInterface. El problema es que el compilador no necesariamente sabe que la estructura es una IMyInterface. El boxeo y el casting te permiten describir tu objeto como un IMyInterface.

Actualmente estoy leyendo sobre esto en CLR Via C# en este momento, así que si crees que he tergiversado esto, por favor corrígeme.

+1

"[E] l compilador no necesariamente sabe que la estructura es un' IMyInterface' "Pero tiene la definición de la estructura, por lo que sabe que implementa la interfaz. – svick

Cuestiones relacionadas