tipizzazione implicita di matrici che implementano interfacce
-
04-10-2019 - |
Domanda
Ho avuto l'impressione che il C # compilatore implicitamente digitare una matrice in base a un tipo che tutti possono essere convertiti in modo implicito.
Il compilatore genera Nessun tipo migliore trovato in serie implicitamente tipizzate
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 };
}
So che il modo per correggere questo è quello di dichiarare il tipo come:
new ISomething [] { obj1, ...}
Ma io sono dopo un sotto le coperte tipo di aiuto qui.
Soluzione
Il compilatore C # considera l'insieme di tipi di tutti gli elementi specificati. Lo fa non considerano tipi di base comune, ecc.
potrebbe Cast una delle espressioni:
var objects= new [] { obj1, obj2, (ISomething) obj3 };
... ma personalmente mi basta usare la forma esplicita:
var objects= new ISomething[] { obj1, obj2, obj3 };
In alternativa, se dichiarato in modo esplicito uno o tutti obj1
, obj2
e obj3
come tipo ISomething
, che avrebbe funzionato bene anche senza cambiare l'espressione di inizializzazione array.
Dal spec C # 3, sezione 7.5.10.4:
Una creazione matrice espressione terza forma viene indicato come un creazione dell'array implicitamente tipizzato espressione . E 'simile al seconda forma, tranne che l'elemento tipo di matrice non è esplicitamente proposta, ma determinato come il migliore tipo corrente (§7.4.2.13) dell'insieme di espressioni nella inizializzatore matrice.
Sezione 7.4.2.13 aspetto:
In alcuni casi, un tipo comune ha bisogno di si impone per un insieme di espressioni. In particolare, i tipi di elementi di array implicitamente tipizzate e il ritorno tipi di funzioni anonime con corpi blocco sono trovati in questo modo. Intuitivamente, dato un insieme di espressioni E1 ... Em questa inferenza dovrebbe essere equivalente a chiamare un Metodo
Tr M<X>(X x1 … X xm)
con il Ei come argomenti. Di Più precisamente, l'inferenza inizia con una variabile di tipo unfixed X. Tipo di uscita inferenze vengono poi fatti da ogni Ei di tipo X. Infine, X è fisso e il tipo risultante è S il tipo comune risultante per la espressioni.
Altri suggerimenti
Se le istanze possono essere gettati al tipo di qualsiasi istanza uno, di quel tipo verrà utilizzato. Non è sufficiente per tutte le istanze di avere qualsiasi tipo in comune, oppure l'inizializzazione di matrice implicitamente sarebbe sempre successo e spesso generano array new object[]
indesiderate.
Come una leggera aggiunta alla risposta del Skeet:
Si può o lanciare uno degli elementi dell'array al tipo è necessario (interfaccia in questo caso) o se si ha solo un singolo elemento di quel tipo (non derivanti, ma di un tipo diretto). Come ad esempio
public static IWindsorInstaller[] MobileRestComponentInstallers
{
get
{
return new []
{
new RepositoryInstaller(),
new AppSettingsInstaller(),
// tens of other installers...
GetLoggerInstaller() // public IWindsorInstaller GetLoggerInstaller()...
};
}
}
questo lavoro volontà, ma i pls non lo fanno :) Basta definire il tipo di matrice e cambiare il new[]
a new IWindsorinstaller[]
.
E 'molto più leggibile avendo il tipo di matrice definito in modo esplicito.
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: qui UIViewController può essere qualsiasi classe