Domanda

I sono la conversione manualmente il codice da Java a C # e alle prese con (quello che io chiamo) tipi primitivi (vedi, ad esempio, fare autoboxing e si comportano in modo diverso unboxing in Java e C # ). Dalle risposte ho capito che double (C #) e Double (C #) sono equivalenti e double (C #) può essere utilizzato anche in contenitori, per esempio come una chiave in un dizionario. Tuttavia, double (Java) non può essere utilizzato in contenitori come HashMap è per questo che è auto-boxed a Double (Java).

  1. È double (C #), un primitivo o di un oggetto?
  2. Se si tratta di una primitiva ciò che lo rende si comportano diversamente da double (Java)?

double (C #) non può essere impostato su null a meno che non si è fatto nullable.

  1. È double? (C #) equivalente a Double (Java)? Sono entrambi indicati come oggetti?

(è l'uso del termine "oggetto di prima classe" utile in questa discussione?)

È stato utile?

Soluzione

Sia C # e Java hanno tipi primitivi (o "valore"): int, double, float, ecc ...

Tuttavia, dopo questo C # e Java tendono a dividere.

Java ha tipi classe wrapper per tutti i tipi primitivi (che è un piccolo insieme finito in Java) che permette loro di essere trattati come oggetti. double/Double, int/Integer, bool/Boolean, ecc Questi tipi di involucro sono riferimento tipi (leggi: classi) e, come tali, null è un valore valido per assegnare a tali espressioni / variabili tipizzate. Le versioni recenti di Java (1.5 / 5 +) aggiungere in coercizioni impliciti dalle primitive per il loro involucro corrispondente.

// Java
Boolean b = true; // implicit conversion boolean -> Boolean (Java 5+)
Boolean b = null; // okay, can assign null to a reference type
boolean n = null; // WRONG - null is not a boolean!

C # non fornisce un un involucro così diretta 1 - in parte, perché C # supporta un insieme infinito di tipi di valore via strutture ; piuttosto, C # gestisce "tipi di valore nullable" con l'introduzione di un Nullable<T> tipo involucro. Inoltre C #, come Java, ha conversioni implicite dal tipo di valore T a Nullable<T>, con la restrizione che T "non è un tipo nullable" stesso.

// C#
Nullable<bool> b = true; // implicit conversion bool -> bool?
bool? b = true;          // short type syntax, implicit conversion
bool? b = null;          // okay, can assign null as a Nullable-type
bool b = null;           // WRONG - null is not a bool

Si noti che Nullable<T> è anche un tipo di valore e quindi segue le regole di struttura standard per quando / se un valore è "in pila" o meno.

In risposta al commento:

Assolutamente corretto, Nullable è un valore di tipo non permettono di avere un consumo di memoria più compatto in taluni casi come si può evitare il sovraccarico della memoria di un tipo di riferimento: Qual è l'occupazione di memoria di un Nullable . Tuttavia richiede ancora più memoria di tipo non Annullabile perché deve ricordare se il valore è, così, null, oppure no. A seconda problemi di allineamento e l'attuazione VM, questo può o non può essere significativamente inferiore a quello di un oggetto "pieno". Inoltre, dal momento che i valori in C # / CLR sono reificati, prendere in considerazione tutte le operazioni di sollevamento che devono essere eseguite:

// C#
object x = null;
x = (bool?)true;
(x as bool?).Value // true

L'articolo Java Suggerimento 130: Sai i dati dimensioni? parla circa il consumo di memoria tipo di riferimento (in Java). Una cosa da notare è che la JVM è specializzata versioni di array interno, uno per ogni tipo primitivo e per gli oggetti (tuttavia, si prega di notare che questo articolo contiene alcune dichiarazioni fuorvianti ). Si noti come gli oggetti (vs. primitive) incorrono in testa memoria aggiuntiva e le problematiche di allineamento di byte. C # tuttavia, può estendere il caso ottimizzato-array per tipi Nullable<T> contro le limitate le speciali vetrine JVM contiene perché Nullable<T> è essa stessa solo un tipo di struttura (o "primitiva").

Tuttavia, un oggetto, richiede solo una piccola dimensione fissa per mantenere un "riferimento" ad esso in una fessura variabile. Una slot variabile di tipo Nullable<LargeStruct> invece, deve avere spazio per LargeStruct+Nullable (fessura stessa può essere sul mucchio). Vedere C # Concetti: Valore vs tipi di riferimento . Si noti come nell'esempio "lifting" al di sopra della variabile è di tipo object:. object è il "tipo root" in C # (genitore di entrambi i tipi di riferimento e tipi di valore) e non un tipo di valore specializzata


1 Il linguaggio C # supporta un insieme fisso di alias per i tipi primitivi / comuni che consentono l'accesso ai nomi tipo "amichevole minuscole". Ad esempio, double è un alias per System.Double e int è un alias per System.Int32. A meno che un diverso tipo Double è importata portata, double e Double faranno riferimento allo stesso tipo in C #. Mi consiglia di utilizzare gli alias a meno che non ci sia una ragione per fare altrimenti.

Altri suggerimenti

Nullable<double> (aka double?) in C # è non la stessa di un Double in Java.

Prima di Java aveva autoboxing / unboxing, si doveva convertire manualmente tra le primitive e oggetti di prima classe:

Double dblObj = new Double(2.0);
double dblPrim = dblObj.doubleValue();

In Java 1.5 che ha cambiato, quindi si può solo fare:

Double dblObj = 2.0;
double dblPrim = dblObj;

E Java sarebbe inserire il codice per rispecchiare l'esempio di cui sopra automaticamente.

C # è diverso perché c'è un numero illimitato di tipi "primitivi" (quello che le chiamate CLR tipi di valore ). Questi si comportano per lo più come primitivi di Java, utilizzando semantica di valore . È possibile creare nuovi tipi di valore utilizzando la parola chiave struct. C # ha autoboxing / unboxing per tutti tipi di valore, e rende anche tutti i tipi di valore derivano da Object.

Quindi, è possibile utilizzare un tipo di valore (come double) in cui si desidera utilizzare alcun riferimento a un oggetto (ad esempio come una chiave in una Dictionary) e sarà in scatola, se necessario, o semplicemente utilizzato direttamente. (Implementazione C # 's Generics è abbastanza buono per evitare di boxe nella maggior parte dei casi).

In C #, il modo migliore per separare gli oggetti sono da "Tipi di valore", che sono un po 'come primitivi - ints, bools, ecc e "tipi di riferimento." - classi etc

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top