2015-06-18 21 views
7

Per quanto ne so, le interfacce non possono essere istanziate.Perché è possibile l'istanziazione della variabile di interfaccia?

Se questo è vero, perché il codice seguente viene compilato ed eseguito? Ti permette di creare un'interfaccia variabile. Perché è possibile?

Interfaccia:

public interface IDynamicCode<out TCodeOut> 
{   
    object DynamicClassInstance { get; set; } 
    TCodeOut Execute(string value = ""); 
} 

incode:

var x = new IDynamicCode<string>[10]; 

Risultato:

Result

UPDATE:

Succede solo quando la matrice è dichiarata. Non una singola istanza.

+7

si è creato un array. –

risposta

16

Non si sta creando un'istanza di un'interfaccia, ma una matrice di tale interfaccia.

È possibile assegnare un'istanza di qualsiasi classe che implementa IDynamicCode<string> a tale matrice. Dire che avete public class Foo : IDynamicCode<string> { }, è possibile creare un'istanza che e assegnarlo a un elemento di tale matrice:

var x = new IDynamicCode<string>[10]; 
x[5] = new Foo(); 

Instantiating l'interfaccia non sarebbe compilare:

var bar = new IDynamicCode<string>(); 
13

Non stai creando un'istanza dell'interfaccia ; stai creando un array che può contenere un numero di oggetti conforme a IDynamicCode. Inizialmente, le voci hanno il loro valore predefinito, che è null.

6

questa non è la creazione di un'interfaccia variabile

questo creerà un array in cui ogni elemento implementa l'interfaccia. se scrivi x[0] = new IDynamicCode<string>(); otterrai l'errore. tutti gli elementi sono null, quindi è necessario assegnare ciascun elemento di un oggetto che implementa IDynamicCode

3

quando si chiama

var x = new IDynamicCode<string>[10]; 

costruttori non sono chiamati. Sono solo dichiarati.

5

Basta un interessante side-nota:

Anche se non è possibile concettualmente, sintatticamente è infatti possibile creare un'istanza di un interfaccia in circostanze specifiche.

.NET ha qualcosa chiamato CoClassAttribute che indica al compilatore di interpretare l'interfaccia contrassegnata come tipo concreto specificato.Utilizzando questo attributo renderebbe il seguente codice perfettamente valido e non lanciare un errore di compilazione (notare che questo non è un array come nel post originale):

var x = new IDynamicCode<string>(); 

Una tipica dichiarazione di tale attributo sarebbe simile a questa:

[ComImport] 
[Guid("68ADA920-3B74-4978-AD6D-29F12A74E3DB")] 
[CoClass(typeof(ConcreteDynamicCode<>))] 
public interface IDynamicCode<out TCodeOut> 
{ 
    object DynamicClassInstance { get; set; } 
    TCodeOut Execute(string value = ""); 
} 

Questo attributo dovrebbe mai essere utilizzato e se, quindi dove? La risposta è "per lo più mai"! Tuttavia, ci sono un paio di scenari specifici per l'interoperabilità COM in cui questo fornirà una funzionalità utile.

Maggiori informazioni possono essere letti sul tema dai seguenti link:

+3

Non stai ancora installando un'interfaccia. Stai utilizzando un tipo di interfaccia in una * nuova espressione *, ma stai creando un'istanza di un oggetto proxy che implementa tale interfaccia. Vale la pena notare che questo è un caso in cui una * nuova espressione * non darà un oggetto del tipo specificato nell'espressione. –

+0

Questo è completamente vero. Anche se la sintassi di tale espressione è ciò che può essere considerato "istanziare un'interfaccia" mentre in realtà un oggetto concreto viene istanziato dietro la scena attraverso la conoscenza del compilatore del CoClassAttribute. –

+0

Entrambi state dicendo la stessa cosa, ma preferisco il modo di affermarlo di @Laurent LA RIZZA. In questo scenario, stai rendendo _look_ come se stessimo istanziando un'interfaccia, quando in effetti stai istruendo il compilatore a utilizzare una classe proxy come tipo di sostituzione predefinito per l'interfaccia. Dal momento che Java è fortemente focalizzato sull'incapsulamento e la _aspetto_del codice può essere personalizzata indipendentemente dalla sua funzionalità (e questo è abbastanza comune), ritengo sia importante essere chiari in casi "strani" come questo che questo non è un hack, e non viola in alcun modo le regole della lingua. –