3

キャスト先の値の型をボックス化するにSystem.Objectは、それ自体が「間違っている」ように見えます(キャストでは値を別の型に変換する必要があるため(したがって、オブジェクトにはインスタンスがないため、Int32をオブジェクトに変換することはデータ損失のあるアクションになるはずです)独自の状態)またはインターフェイスポインタを親に変換する(これは、ポイントされているオブジェクトの状態に影響を与えず、コンパイル時の問題です)。CLRで値型をボックス化する場合、値をコピーします。最初のタスク(値をヒープにコピーするか、少なくともその値への参照を取得する)だけを本当に実行したい場合は、ヒープに同時にインターフェイス情報を失います。

Javaは、との強力なタイプを使用してこの問題を解決しIntegerますLong。なぜ.NETにこれがないのですか?

他のプロジェクトに含めたいユーティリティソースコードの独自のコレクションがあり、それらには、暗黙的および明示的な変換演算子をオーバーライドする、厳密に型指定されたボックス化されたクラス(BoxedInt32など)の独自の実装が含まれているため、オブジェクトにキャストすることは、実際にオブジェクトにキャストする必要がないことを除いて、行います(したがって、型データを保持します)。だから私はこれを行うことができます:

private BoxedInt32 _reference;
public Int32 GetValue{ return _reference; }

では、なぜ.NETは、4つのメジャーリリースの後、まだ強く型付けされたボックス型を持たないのでしょうか。

4

3 に答える 3

4

意味がありません。BoxedInt32を直接使用することは決してありません。事前にタイプを知っていればint、ボックスの代わりに使用するのが賢明だからです。したがって、唯一の興味深いケースは、タイプが事前にわからないobject場合、つまりを処理する場合です。まあ、値型ボクシングはすでにそれを完全に処理し、型をとして報告しInt32ます。

特定のボックス化されたバージョンがJavaに存在する理由の一部は、Javaジェネリックが型消去によって非常に異なる動作をするためです。ただし、.NETには値型を含む真のジェネリックが含まれているため、これは不要です。

あなたはあなた自身の箱を作ることができます:

public class Box<T> where T : struct {
    private readonly T value:
    public Box(T value) { this.value = value; }
    public T Value { get { return value; } }
}

(おそらく、変換/平等などの機能をさらに追加します):しかし-繰り返しますが:まったく意味がありません。通常の作り付けのボクシングはすでにこれをはるかにうまく処理します。

于 2012-09-03T02:34:01.577 に答える
1

問題の根本は、キャストがどのように機能し、それが何のためにあるのかについての誤解のようです。

(キャストは値を別のタイプに変換するか、インターフェイスポインタを親に変換する必要があるため)

あるものを別のものにキャストするときに発生するのは、コンパイラに「このランダムなビットのコレクションを少し異なる方法で処理してください」と伝えることだけです。ビットが変換または変更されることはまったく想定されていません。C#とJavaは安全のためにタイプチェックインをスローしますが、それはキャスト操作自体の中心ではありません。

int32を表すビットのコレクションを他のもの(オブジェクト参照など)として扱うことは無意味であるため、Boxingシステムは背後にあり、ラッパーを生成します。それはまだキャストのルールに従っています-コンパイラはこのボクシングラッパーをオブジェクト参照として扱うことができ、元のビットは変更されません

...実際にオブジェクトにキャストする必要がない場合を除いて(したがって、型データを保持します)...

繰り返しますが、これは誤った仮定に基づいています。上記の説明に沿って、キャストは値を変更しないという事実により「型データを保持」し、コンパイラがそのデータを解釈する方法を変更するだけです。ボックス化によって生成されたラッパーは、基になるデータに引き続きアクセスできます。-ボックス化されたintで.GetType()を呼び出すと、Int32であることが喜んで報告されます。あなたのBoxedInt32クラスは、すでに利用可能なデータを保存するために時間とスペースを浪費しているだけです。

**注:C#でキャストしているように見えるコードが、暗黙の変換演算子を呼び出すことによって実際にデータを変換する場合があります。これはキャストではなく、ふりをしているだけなので、ルールは適用されません。

于 2012-09-03T04:38:01.767 に答える
0

多分それはこの場合に便利でしょう:

var myDictionary = new Dictionary<int, bool>();

// So we could use a BoxedBool here and modify the
// value set below.
//var myDictionary = new Dictionary<int, BoxedBool>();

myDictionary.Add(1, true);
myDictionary.Add(2, false);

foreach (var key in myDictionary.Keys)
{
    myDictionary[key] = false;
    // Cannot do this as it modified the collection.
    // If it was a reference type, this would not be a problem?
}
于 2014-01-28T05:49:00.267 に答える