2015-02-25 6 views
15

Secondo this post int è il tipo di supporto per enum.Come int è il tipo di supporto per enum

Quando controllo il codice sorgente di .NET System.Enum classe astratta eredita dalla classe astratta System.ValueType.

Ma quando controllo la struttura System.Int32 eredita dalle interfacce ma non da System.ValueType.

Al contrario, quando ho decompilare mscorlib.dll e controllare il Int32 struct si dice che la struttura ha tipo di base di System.ValueType.

enter image description here

Ma ancora il controllo del codice sorgente decompilato non riesco a vedere nulla di System.ValueType.

enter image description here

mi fa pensare che la parola chiave struct rende il decleration auto-Sytem.ValueType, che Microsoft denota anche in questo reference.

Ma ho ancora una domanda. Per quanto ne so, l'ereditarietà di due classi diverse dallo stesso genitore non implica che si erediti anche da altri. Voglio dire se se B:A e C:A questo non significa sempre che C:B.

Inoltre, quando controllo i codici sorgente System.Enum ha un'implementazione del tutto diversa da System.Int32.

Torna alle origini, in queste circostanze, come si ottiene il risultato che "System.Int32" è il tipo di supporto per System.Enum?

Qualcuno può spiegare?

Saluti.

+2

Vedere http://stackoverflow.com/a/3504145/1625737 – haim770

+3

"Tutti i tipi di valore sono derivati ​​** implicitamente ** dal System.ValueType." (Https://msdn.microsoft.com/en-us/library/s1ax56ch.aspx). – haim770

+2

Decisamente non off-topic. È possibile eliminare la parte P.S :) –

risposta

9

Int32 è solo il tipo di base predefinito per enum, tuttavia è modificabile. Puoi modificare ciò specificando un diverso tipo di dati, ad es.

enum ExampleEnum : byte 
{ 
    Value1, 
    Value2, 
    Value3 
}; 

Ecco cosa dice di Microsoft per quanto riguarda l'enum:

Ogni tipo di enumerazione ha un tipo di fondo, che può essere qualsiasi tipo integrale tranne char.
Il tipo di elementi di enumerazione sottostante predefinito è int.
dichiarare un enum di un altro tipo integrale, come ad esempio byte, utilizzare i due punti dopo l'identificatore seguito dal tipo,
...
I tipi approvati per un enum sono byte, sbyte, insomma, ushort, int, uint, long o long.

^Source MSDN: enum (C# Reference)

+0

Grazie mille @AeroX. – user3021830

1

int e enum sono due cose molto diverse, ad esempio è possibile calcolare (aggiungere/sottrarre) con numeri interi, che non è possibile fare con enumerazioni. Quindi è chiaro che l'impalmentazione di entrambi è molto diversa.

Ancora un enum è memorizzato allo stesso modo di un numero intero (in genere una posizione di memoria a 32 bit) e vi è una conversione 1: 1 tra valori enum e valori int.

In questo senso int è un tipo di supporto per un enum.

+0

Grazie mille per il tuo aiuto @DrKoch. È stato utile – user3021830

12

Stai confondendo enum (la parola chiave C# per definire un tipo di enumerazione) e Enum (la classe che un tale tipo di enumerazione deriva).

using System; 
using System.Reflection; 

enum Foo { A, B, C }; 

static class Program { 
    static void Main() { 
    foreach (var field in typeof(Foo).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 
     Console.WriteLine("Found instance field \"" + field.Name + "\" of type \"" + field.FieldType.FullName + "\""); 
    } 
} 

Sul mio sistema, Questo stampa

 
Found instance field "value__" of type "System.Int32" 

Questo perché Foo viene efficacemente definito come (pseudo-codice, non è valida C#)

struct Foo : Enum { 
    int value__; 
} 

insieme a qualche supporto del compilatore in più , alcuni campi extra statici per elencare i membri dell'enum, ma l'idea di base rimane la stessa.

Il tipo di backup è definito come parte di ciascun tipo di enumerazione del calcestruzzo, non come parte di System.Enum. Non potrebbe essere, perché potrebbe essere diverso per due tipi di enumerazione distinti.

+0

Grazie mille per la tua spiegazione @hvd. – user3021830

3

Hai trovato scollarsi a causa della differenza tra eredità e rappresentazione.

Solo perché B eredita da A non significa che B è rappresentato (supportato) da A.

Un Enum può ereditare da ValueType, ma essere rappresentato (supportato) da int.

E 'un po' come una classe può ereditare da PersonObject da essa utilizza string (Nome) e int (Age) come i tipi backing per la classe.

L'importante, fondamentale, è che il compilatore fa un po 'di magia quando si tratta di un certo numero di tipi. ValueType eredita da Object ma non è un tipo di riferimento perché il compilatore si occupa in modo specifico.

Un Enum è uno speciale ValueType che ha un tipo di backup creato automaticamente - int per impostazione predefinita - e tutto dipende dal compilatore.

+0

Grazie mille per i vostri sforzi @Enigmativity. – user3021830