質問

私は手動でコードをJavaからC#に変換しており、(私が呼んでいる)プリミティブ型に苦労しています(たとえば、 オートボックス化とボックス化解除は Java と C# で異なる動作をしますか?)。回答から分かるのですが、 double (C#) と Double (C#) は同等であり、 double (C#) はコンテナーでも使用できます。辞書のキーとして。しかし、 double (Java) は HashMap のようなコンテナでは使用できないため、自動的にボックス化されます。 Double (ジャワ)。

  1. double (C#) プリミティブですか、それともオブジェクトですか?
  2. それがプリミティブの場合、何が異なる動作をするのか double (ジャワ)?

double (C#) を作成しない限り null に設定することはできません nullable.

  1. double? (C#) と同等 Double (ジャワ)?両方ともオブジェクトと呼ばれますか?

(この議論では「ファーストクラス オブジェクト」という用語の使用が役に立ちますか?)

役に立ちましたか?

解決

C# と Java の両方にプリミティブ (または「値」) 型があります。int、double、floatなど...

しかし、この後はC#とJavaが分かれる傾向にあります。

Javaにはラッパークラスタイプがあります。 すべてのプリミティブ型 (これは Java の小さな有限セットです) これにより、それらをオブジェクトとして扱うことができます。double/Double, int/Integer, bool/Boolean, 、など。これらのラッパー型は参照型です (以下を参照)。クラス)、そしてそれ自体、 null は、そのような型付き式/変数に割り当てる有効な値です。Java の最近のバージョン (1.5/5+) では、プリミティブから対応するラッパーへの暗黙的な強制が追加されています。

// 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# ではそのような直接的なラッピングは提供されません1 - 部分的には、C# がサポートしているためです。 値の型の無限のセット 経由 構造物;むしろ、C# は、 Nullable<T> ラッパータイプ。さらに、C# には Java と同様に、値の型からの暗黙的な変換があります。 TNullable<T>, ただし、T 自体は「null 許容型ではない」という制限があります。

// 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

ご了承ください Nullable<T> も値型であるため、値が「スタック上」にあるかどうかについての標準構造規則に従います。

コメントへの返信:

まったくその通りです。Nullable は値型であるため、メモリ使用量をよりコンパクトにできます。 場合によっては 参照型のメモリ オーバーヘッドを回避できるためです。 Nullable<T> のメモリ フットプリントはどれくらいですか?. 。ただし、値が null であるかどうかを記憶する必要があるため、Null 非許容型よりも多くのメモリが必要になります。アライメントの問題と VM の実装に応じて、これは「完全な」オブジェクトより大幅に少なくなる場合もあれば、そうでない場合もあります。また、C#/CLR の値は具体化されるため、実行する必要があるリフティング操作を考慮してください。

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

記事 Java ヒント 130:データサイズを知っていますか? 参照型のメモリ消費 (Java の場合) について説明します。注意すべき点の 1 つは、JVM が内部的にプリミティブ型とオブジェクトごとに 1 つずつ、特殊なバージョンの配列を持っていることです (ただし、この記事には一部の配列が含まれていることに注意してください) 誤解を招く発言)。オブジェクト (vs.プリミティブ)は、余分なメモリ オーバーヘッドとバイト アラインメントの問題を引き起こします。ただし、C# では、最適化された配列のケースを拡張できます。 Nullable<T> タイプとJVM が持つ特殊なケースは限られているため、 Nullable<T> それ自体は単なる構造タイプ (または「プリミティブ」) です。

ただし、オブジェクトは、変数スロット内でオブジェクトへの「参照」を維持するために小さな固定サイズのみを必要とします。タイプの可変スロット Nullable<LargeStruct> 一方、スペースが必要です LargeStruct+Nullable (スロット自体がヒープ上にある場合があります)。見る C# の概念:値と参照型. 。上記の「リフティング」の例では、変数の型がどのようになっているのかに注目してください。 object: object C# の「ルート型」 (参照型と値型の両方の親) であり、 ない 特殊な値タイプ。


1 C# 言語は、次の固定セットをサポートしています。 エイリアス 「フレンドリーな小文字」型名へのアクセスを許可するプリミティブ/共通型の場合。例えば、 double のエイリアスです System.Double そして int のエイリアスです System.Int32. 。別の場合を除き、 Double 型はスコープ内にインポートされます。 double そして Double C# では同じ型を参照します。特別な理由がない限り、エイリアスを使用することをお勧めします。

他のヒント

Nullable<double> (別名 double?) C# では ない と同じ Double ジャワでは。

Java にオートボックス化/アンボックス化が導入される前は、プリミティブとファーストクラス オブジェクトの間で手動で変換する必要がありました。

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

Java 1.5 ではそれが変更されたため、次のようにするだけで済みます。

Double dblObj = 2.0;
double dblPrim = dblObj;

そして、Java は上記の例を自動的に反映するコードを挿入します。

C# は、「プリミティブ」型 (CLR で呼ばれるもの) が無制限に存在するため異なります。 値の型)。これらは主に Java のプリミティブと同様に動作します。 値のセマンティクス. 。新しい値の型を作成するには、 struct キーワード。C# にはオートボックス化/アンボックス化があります 全て 値の型を定義し、すべての値の型を次から派生させます。 Object.

したがって、値型を使用できます(次のように) double) 任意のオブジェクト参照を使用します (例:のキーとして Dictionary) 必要に応じてボックスに入れられます。そうでない場合は、そのまま使用されます。(C# のジェネリック実装は、ほとんどの状況でボックス化を回避するのに十分です。)

ints、bools、などと「参照タイプ」 - -

でC#、別のオブジェクトへの最善の方法は、プリミティブのようにちょっとある「値のタイプ」である。クラスなど

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top