2010-05-10 19 views
9

Tenía la impresión de que el compilador de C# tipearía implícitamente una matriz basada en un tipo al que todas pueden convertirse implícitamente.Mecanografía implícita de matrices que implementan interfaces

el compilador genera n mejor tipo encontrado para conjunto de tipos implícita-

public interface ISomething {} 

public interface ISomething2 {} 

public interface ISomething3 {} 

public class Foo : ISomething { } 
public class Bar : ISomething, ISomething2 { } 
public class Car : ISomething, ISomething3 { } 

void Main() 
{ 
    var obj1 = new Foo(); 
    var obj2 = new Bar(); 
    var obj3 = new Car(); 

    var objects= new [] { obj1, obj2, obj3 }; 
} 

Yo sé que la manera de corregir esto es declarar el tipo como:

new ISomething [] { obj1, ...} 

Pero Estoy después de un debajo de las coberturas, escribe ayuda aquí.

+0

como en qué el compilador no tratar de encontrar un tipo de juego? –

Respuesta

14

El compilador de C# considera el conjunto de tipos de todos los elementos especificados. Lo hace no consideran tipos de bases comunes etc.

Usted podía lanzas una de las expresiones:

var objects= new [] { obj1, obj2, (ISomething) obj3 }; 

... pero personalmente me gustaría sólo tiene que utilizar la forma explícita:

var objects= new ISomething[] { obj1, obj2, obj3 }; 

Alternativamente, si declaró explícitamente alguno o todos obj1, obj2 y obj3 como tipo ISomething, eso haría funciona bien también sin cambiar la expresión de inicialización de la matriz.

De la especificación C# 3, la sección 7.5.10.4:

Una expresión creación de la matriz de la tercera forma se conoce como un implícitamente mecanografiado creación de la matriz expresión. Es similar a la segunda forma , excepto que el tipo elemento de la matriz no está explícitamente dado, pero se determina como el mejor tipo común (§7.4.2.13) del conjunto de expresiones en el inicializador de matriz.

Sección 7.4.2.13 es similar al siguiente:

En algunos casos, un tipo común tiene que ser inferidas para un conjunto de expresiones. En particular, se encuentran los tipos de elemento de matrices implícitamente tipadas y los tipos de retorno de funciones anónimas con cuerpos de bloque de esta manera. Intuitivamente, dado un conjunto de expresiones E1 ... Em esta inferencia debería ser equivalente a llamar a un método

Tr M<X>(X x1 … X xm) 

con el Ei como argumentos.Más precisamente, la inferencia comienza con un tipo sin fijar la variable X. inferencias Tipo de salida se hacen entonces de cada Ei con el tipo X. Por último, X es fijo y el tipo resultante S es el tipo común resultante para el expresiones.

3

Si todas las instancias se pueden convertir al tipo de una instancia, se usará ese tipo. No es suficiente que todas las instancias tengan ningún tipo en común, de lo contrario, la inicialización de la matriz de implícita siempre tendrá éxito y a menudo generará matrices new object[] no deseadas.

0

Como un ligero además de la respuesta del Skeet:

que puede convertirlo uno de los elementos de matriz del tipo que necesita (interfaz en este caso) o si ha tenido un solo elemento de ese tipo (no deriva sino de un tipo directo). Tal como

public static IWindsorInstaller[] MobileRestComponentInstallers 
     { 
      get 
      { 
       return new [] 
          { 
           new RepositoryInstaller(), 
           new AppSettingsInstaller(), 
           // tens of other installers... 
           GetLoggerInstaller() // public IWindsorInstaller GetLoggerInstaller()... 
          }; 
      } 
     } 

esto va a funcionar, pero los pls no hacen eso :) Sólo a definir el tipo de matriz y cambiar el new[]-new IWindsorinstaller[]. Es mucho más legible teniendo el tipo de matriz definido explícitamente.

0
Do like this for Class object(UIViewController) initialization in var array: 



var page1 = new Class1(); 
var page2 = new Class2(); 
var pages = new UIViewController[] { page1, page2 }; 

Nota: aquí UIViewController puede ser cualquier clase

Cuestiones relacionadas