web-dev-qa-db-ja.com

Typeクラスで記述された型にオブジェクトをキャストする方法は?

オブジェクトがあります:

ExampleClass ex = new ExampleClass();

そして:

Type TargetType

次のように、TargetTypeで記述された型にexをキャストしたいと思います。

Object o = (TargetType) ex;

しかし、これを行うと次のようになります:

タイプまたは名前空間名 't'が見つかりませんでした

それでこれをどうやってやるの?ここで何か奇妙なものを見逃していますか?

更新:

私はこのようなものを取得したいと思います:

public CustomClass MyClassOuter
{
   get
   {
        return (CustomClass) otherClass;
   }
}

private otherClass;

そして、私はこのような多くのプロパティを持っているので、私はこれをやりたいです:

public CustomClass MyClassOuter
{
   get
   {
        return (GetThisPropertyType()) otherClass;
   }
}

private SomeOtherTypeClass otherClass;

環境:

通常、クラスのコンテキストでは、多くのプロパティを作成する必要があります。そして、いずれの場合も、キャストをプロパティのタイプに置き換えます。私の戻り値の型が何であるかを知っているので、私にとっては意味がないようです(私のコンテキストでは)。多分それはジェネリックの場合かもしれませんが、私はまだ知りません。

このプロパティで正しいオブジェクトと正しい型を取得し、それをプロパティ型に100%キャストできることを保証できるようです。

これを行う必要があるのは、すべてのプロパティで「CustomClassに値をキャストする」必要があることを指定する必要がないようにするためです。「このプロパティと同じクラスに値をキャストする」ようなことをしたいと思います。

例えば:

class MYBaseClass
{
   protected List<Object> MyInternalObjects;
}

class MyClass
{
   public SpecialClass MyVeryOwnSpecialObject
   {
      get
      {
           return (SpecialClass) MyInteralObjects["MyVeryOwnSpecialObject"];
      }
   }
}

そして、OK-上記のような多くのプロパティを作成できます-しかし、2つの問題があります:

1)MyInternalObjectsでオブジェクトの名前を指定する必要がありますが、プロパティ名と同じです。これはSystem.Reflection.MethodBase.GetCurrentMethod()。Nameで解決しました。

2)すべてのプロパティで、オブジェクトをMyInternalObjectsからさまざまな型にキャストする必要があります。たとえばMyVeryOwnSpecialObjectで-SpecialClassに。常にプロパティと同じクラスです。

それが私がこのようなことをしたい理由です:

class MYBaseClass
{
   protected List<Object> MyInternalObjects;
}

class MyClass
{
   public SpecialClass MyVeryOwnSpecialObject
   {
      get
      {
           return (GetPropertyType()) MyInteralObjects[System.Reflection.MethodBase.GetCurrentMethod().Name];
      }
   }
}

そして今懸念事項:わかりました、何のためですか?私のアプリケーションでは、安全なタイプなどのすべての利点(インテリセンス)が得られるためです。

2つ目:しかし、今、あなたはこの場所で型安全性を失いますか?いいえ。リストに自分のタイプのオブジェクトがあると確信しているからです。

27

今では不可能に思えますが、すぐに「ダイナミック」と呼ばれる.NET 4.0の新機能で利用可能になります。

http://www.codeguru.com/vb/vbnet30/article.php/c15645__4/

1
Object o = (TargetType) ex;

このコードは役に立ちません。あなたは右側にタイプを持っているかもしれませんが、それはまだ左側のオブジェクトにすぎません。このようなTargetTypeに固有の機能は使用できません。


これは、特定のタイプの未知のオブジェクトのメソッドを呼び出す方法です。

object myObject = new UnknownType();
Type t = typeof(UnknownType); // myObject.GetType() would also work
MethodInfo sayHelloMethod = t.GetMethod("SayHello");
sayHelloMethod.Invoke(myObject, null);

このUnknownTypeクラスの場合:

class UnknownType
{
    public void SayHello()
    {
        Console.WriteLine("Hello world.");
    }
}
11
weiqure

通常、これを行うという欲求は誤解を示します。ただし、これを行う正当な理由は非常にまれですare。それは参照変換対ボックス化解除またはユーザー定義変換のどちらになるかによって異なります。

参照変換の場合、実際の値(参照)はまったく変更されないままになります。キャストは、チェックを実行してから値をコピーするだけです。これには実際の使用法はありません。代わりにType.IsAssignableFromを使用してチェックを実行し、object型の変数で必要な場合はobjectへの暗黙のキャストを使用できます。

キャストの主な目的は、compilerに詳細情報を提供することです。これで、executionの時点で型しかわからない場合、それは明らかにコンパイラに役立ちません。

キャストを実行した後、oで何をする予定ですか?説明できる場合は、目的の効果を達成する方法を説明することができます。

ユーザー定義の変換またはボックス化解除の変換が本当に必要な場合、それは別の問題かもしれませんが、Isuspectはそうではありません。

編集:更新を見た後、プロパティはCustomClassを返すように宣言されているので、必要なのは次のとおりです:

public CustomClass MyClassOuter
{
   get
   {
        return (CustomClass) otherClass;
   }
}

必要な情報をまだすべて提供していないのではないかと思います。それは、definitelyプロパティーがどのように定義されるのか、CustomClassは確定型ですか?プロパティタイプがわかっているのに、なぜキャストを動的に実行しようとしたのですか?

編集:いくつかの入力を保存しようとしているように聞こえます-カットアンドペーストを簡単にするためです。しないでください。コンパイル時にプロパティの型を知っているので、コンパイル時に型を知っています(上のコードのほんの数行で指定されています)。そのタイプを直接使用します。同様に、使用するキーを見つけるために現在のメソッドの名前を取得しようとしないでください。名前を直接入力するだけです。繰り返しますが、コンパイル時にそれを知っているので、なぜ動的であるのですか?それは理にかなっているとき私はすべて怠forのためです、しかしこの場合それはちょうどそうではありません。

3
Jon Skeet

私はあなたが何をしようとしているのか完全にはわかりませんが、私が得ている印象は、あなたが多くの異なるタイプのオブジェクトのように動作できるオブジェクトの単一のインスタンスを持ちたいということです。これらのさまざまな方法でこの1つのオブジェクトを非常に簡単に表示できるゲッターがあります。その場合、次のように(プロパティではなく)単一のgetterメソッドを作成することをお勧めします。

public T Get<T>()
{
   return (T)myObject;
}

次に、次のように呼び出します。

Foo foo = box.Get<Foo>();
Bar bar = box.Get<Bar>();
// etc...

次の2つの点に注意してください。キャストに失敗する型を含め、Tに任意の型を渡すことができるため、これは間違いなく型セーフではありません。次のように、少し制限することができます。

public T Get<T>() where T : SomeBaseType

SomeBaseTypeと互換性のない型を使用しようとすると、コンパイルエラーが発生しますが、完全に堅牢であるかどうかはわかりません。しかし、うまくいけば、これでほとんどの方法が得られます。

これはあなたが念頭に置いていたものですか?

1
gzak
if (ex is ExampleClass) 
{
  ExampleClass myObject = (ExampleClass)ex;
}

それでうまくいきますが、質問は何を達成しようとしているのか、なぜですか?私はしばしば、何かが本当に本当に思える場合、本当に難しい場合、おそらくそれを間違っていると思います。

0
Lazarus