4

だから私はこれがうまくいくことを知っています:

class A
{
}
class B : A
{       
}

[Test]
public void CanCast()
{
    Assert.That(typeof(A).IsAssignableFrom(typeof(B)));
    Assert.That(!typeof(B).IsAssignableFrom(typeof(A)));
}

ただし、これら2つのタイプがInt32とInt64であったとしましょう。

実行時に、Int32値をInt64変数にキャストできますが、その逆はできません。実行時にこの種のキャスト互換性を確認するにはどうすればよいですか?(IsAssignableFromはこれでは機能しません。これは、Int32およびInt64では常にfalseになります)

編集:私はそれらのタイプの値を持っていないので、単純にキャストを試みることはできません。私は2つのタイプAとBを持ち、2つの値aとbを持たないという架空のシナリオを求めています。

4

2 に答える 2

6

非プリミティブ型の場合op_Implicit、変換をサポートするメソッドがいずれかの型にあるかどうかを反映して検査できます。ILは実際には真の演算子のオーバーロードをサポートしていないため、C#が演算子のオーバーロードを認識するのは純粋に慣例的なシステムです。このメソッドは、C#の演算子オーバーロード定義から作成された場合も、IsSpecialNameとマークされます。

プリミティブ型(Int32やInt64など)の場合、変換はメソッドではなくプリミティブILオペコードを介して行われるため、最も簡単なオプションはさまざまなケースをハードコーディングすることです。ただし、プリミティブ型はほんの一握りなので、各プリミティブ型のすべての可能性をチェックするメソッドを作成することは難しくありません。

あなたの例ではプリミティブ値型について具体的に言及しているので、1つの注意点として、暗黙の「変換」(C#)の存在は、すべての「キャスト」が機能することを意味するわけではないことに注意してください。C#キャスト操作(T)xは、「xの値を箱から出してT型にする」ことも意味します。xにボックス化されたInt32が含まれていて、(Int64)xを実行しようとすると、Int32をInt64に暗黙的に「変換」できたとしても、実行時に失敗します。開開がこのように機能する理由の詳細については、EricLippertを参照してください。

于 2012-10-05T21:25:56.603 に答える
-1

1つの(エレガントではない)アプローチは、単にそれを試すことです-試行をtry / catchでラップし、例外をキャッチした場合はfalseをアサートします。

于 2012-10-05T15:30:19.953 に答える