2015-08-05 15 views
6

Ho scritto sotto il codice e si sta compilando con successo.Posso creare il costruttore per Enum?

class Program 
{ 
     enum Fruits 
     { 
      Apple, 
      Mango, 
      Banana 
     } 

     static void Main(string[] args) 
     { 
      Fruits f = new Fruits(); 
     } 
} 

Nonostante Fruits essere un enum, compilatore e interprete stanno permettendo a me di scrivere questo. Questo significa che posso creare un costruttore per un enum? se sì allora come?

+1

cosa ti piacerebbe realizzare con tale costruttore? –

+1

Potrei voler sovrascrivere il comportamento predefinito di restituzione di Apple per impostazione predefinita, solo pensando ad alta voce. – yogi

+0

È possibile modificare quale è l'impostazione predefinita cambiando l'ordine in cui sono elencate le alternative enum. –

risposta

4

No, non è possibile.

new Fruits() restituirà il valore predefinito (il valore corrispondente al 0 nel tipo sottostante dell'enumerazione), è la stessa come default(Fruits) (o Fruits.Apple nel caso).

Ricordare che le enumerazioni sono solo wrapper attorno a un tipo primitivo (int per impostazione predefinita). Si può praticamente confrontare new Fruits() a new int().

Di solito non si usa la sintassi new Fruits()/new int() come è più comune basta scrivere 0 o default(T), ma si possono usare colori in codice generico. Per fare un esempio:

public T NewInstance<T>() 
    where T : new() 
{ 
    return new T(); 
} 

Hai il permesso di chiamare NewInstance<Fruits>(), che restituirà Fruits.Apple.

+0

Syntactic Sugar to 'int' –

+1

' int() 'funziona in .NET 1.0, prima di generici. È un vantaggio, ma non una ragione. –

+0

@Jon Grazie per l'input, ho completamente dimenticato .NET 1.0. Ho riformulato la risposta. –

1

No. Controllare l'uscita IL (generata in LINQPad). In realtà non chiama affatto un costruttore. Invece, memorizza il valore intero 0 all'interno di una variabile locale chiamata f. Questo è lo esatto stesso output che si ottiene quando si utilizza un cast di tipo sull'enumerazione.

Per quanto riguarda il compilatore, Fruits f = new Fruits(); corrisponde a Fruit f = (Fruit)0;.

Fruits f = new Fruits() IL

Program.Main: 
IL_0000: nop   
IL_0001: ldc.i4.0  
IL_0002: stloc.0  // f 
IL_0003: ret   

Program..ctor: 
IL_0000: ldarg.0  
IL_0001: call  System.Object..ctor 
IL_0006: ret 

Per confronto, ecco l'output IL di una classe normale. Guarda IL_001 in Program.Main dove chiama effettivamente un costruttore per la classe.

Program.Main: 
IL_0000: nop   
IL_0001: newobj  UserQuery+Program+Fruits..ctor 
IL_0006: stloc.0  // f 
IL_0007: ret   

Program..ctor: 
IL_0000: ldarg.0  
IL_0001: call  System.Object..ctor 
IL_0006: ret   

Fruits..ctor: 
IL_0000: ldarg.0  
IL_0001: call  System.Object..ctor 
IL_0006: ret   
3

C# Spec:

Un tipo enum è un tipo valore distinto con una serie di costanti denominate.

Quanto al valore predefinito (come spiegato in altra risposta):

Il valore predefinito di qualsiasi tipo enum è il valore integrale di zero convertito nel tipo enum. Nei casi in cui le variabili sono automaticamente inizializzate su un valore predefinito, questo è il valore assegnato alle variabili dei tipi di enumerazione. Affinché il valore predefinito di un tipo di enum sia facilmente disponibile, il valore letterale 0 viene convertito implicitamente in qualsiasi tipo di enum.

Sposta la costante di default per essere la prima nella tua enumerazione.

1

Per qualsiasi tipo di valore, esiste un costruttore senza parametri che restituisce il valore tutto-zero. Quindi:

var val = new int(); // 0 
var val = new double(); // 0.0 
var val = new DateTime(); // 0001-01-01T00:00:00.000000 Unspecified timezone 
var val = new StringSplitOptions(); // StringSplitOptions.None 

Tuttavia:

  1. non è possibile aggiungere un nuovo costruttore per un tipo che non è un struct o un class, e quindi, per quanto di valore tipi vanno, solo struct.
  2. Non è possibile modificare l'implementazione di nessuno di questi costruttori predefiniti.

Nel caso di enum s e primitive il costruttore non è nemmeno dichiarato.

Quindi non è possibile creare un tale costruttore.

(Strettamente parlando, .NET consente di impostare un costruttore senza parametri definito su un struct ma C# non lo fa, e se lo si fa in CIL non elaborato ci sono regole incoerenti rispetto a quando verrà chiamato e quando si otterremo solo un'istanza a zero zero creata).

Problemi correlati