2012-11-01 13 views
24

Non capisco. Il As operator:L'operatore as sulle strutture?

The as operator is used to perform certain types of conversions between compatible reference or nullable types.

allora perché il seguente lavoro?

struct Baby : ILive 
{ 
    public int Foo { get; set; } 

    public int Ggg() 
    { 
     return Foo; 
    } 
} 

interface ILive 
{ 
    int Ggg(); 
} 

void Main() 
{ 
    ILive i = new Baby(){Foo = 1} as ILive; // ?????? 
    Console.Write(i.Ggg());     // Output: 1 
} 
  • Baby è una struttura, creando metterà valore stack. C'è un riferimento a no.

  • Non ci sono certamente tipi nullable qui.

Qualche spiegazione sul motivo per cui ho torto?

+0

Btw, un oggetto mutabile come Baby fa una cattiva struttura. Una classe sarebbe una scelta più ovvia. –

+0

@MarcGravell di corso. ma questa domanda è per conoscere meglio gli scenari limite. :-) –

risposta

34

La sua fusione come interfaccia creerà una copia in scatola sull'heap gestito e restituirà un riferimento alla copia in scatola. La scatola implementa l'interfaccia.

+0

Il fatto che l'interfaccia NON erediti System.object, non ha nulla a che fare con esso? –

+4

@RoyiNamir non per niente. Le interfacce sono sempre tipi di riferimento, con la sola eccezione dei generici, quando possono essere tipi * vincolati * (a metà tra tipo di riferimento e tipo di valore) –

9

Funziona perché il lato destro è un'interfaccia. La condizione è che il lato destro possa accettare come valore null, ovvero un tipo di riferimento o un tipo di valore nullable. Le interfacce sono un tipo di riferimento. In questo caso il codice inserirà la struct e quindi lancerà l'oggetto box all'interfaccia.

+0

Qualsiasi cosa che abbia il tipo statico di un'interfaccia, è un riferimento. Se si esegue il cast di un tipo di valore su un'interfaccia, esso viene inserito in una casella (dandovi un riferimento). Quindi in questo contesto è giustificato chiamarli tipi di riferimento. – CodesInChaos

+0

Esiste, come sempre, un'eccezione * parziale * a "qualsiasi cosa": un'interfaccia quando descritta tramite un vincolo generico su alcuni 'T'. Sebbene la parte "vincolata" si applica solo quando la variabile è 'T' - * not * quando è l'interfaccia stessa. –

0

È sufficiente trasmettere con il tipo di riferimento ILive valore nullable, quindi non viene generato alcun errore. Tuttavia, se provi questo codice commentato, riceverai un errore.

Baby b = new Baby(); 
object o = b; 
//Baby bb = o as Baby ; 

Questo perché si sta cercando di lanciare con as al tipo di valore e che non può essere null.