2013-08-05 9 views
13

Aşağıdaki kod göz önünde yazın:Cast yansıyan C#

object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();} 
MethodInfo methodInfo = typeof(Program).GetMethod("Baz"); // Foo Baz(){return foo;} 
Type typeFoo = methodInfo.ReturnType; 
var result = (typeFoo)objFoo; 

Ben sonuç almak için typeFoo bazı büyü yapmak gerekir mi?

+0

Foo sonucundan sonra ne yapmaya çalıştığınızı anlatabilir misiniz? –

+0

Orijinal kodda, MethodInfo methodInfo = ... gibi bir şeydir. typeFoo = methodInfo.ReturnType; Yani hangi tip olacağını bilmiyorum. – user2341923

+1

Ne tür olduğunu bilmiyorsanız, soldaki değişkeni nasıl bildiriyorsunuz? –

cevap

49

yok :-)

Durum 1: derleme zamanında Foo tip biliyorum çünkü

object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();} 
Foo result = (Foo)objFoo; 

, burada hiçbir yansıması yoktur.

Durum 2: arabirimleri. Normalde

object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();} 
IFoo result = (IFoo)objFoo; 

Vaka 3 ... en iyisi ... Sen tam olarak ne MakeFoo döner bilmiyorum ama bunun bir IFoo arayüzü biliyorum: emin değilseniz MakeFoo döner Foo

benzer
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();} 

if (objFoo is Foo) 
{ 
    Foo result = (Foo)objFoo; 
} 

veya

object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();} 

Foo foo = objFoo as Foo; 

if (foo != null) 
{ 
    // use foo 
} 

Durum 4: tip Foo, programınız için tamamen bilinmemektedir. Sen

object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();} 
Type typeFoo = objFoo.GetType(); // You should check for null values before! 

// and now? 

dynamic foo = objFoo; 

// because you know that foo can Quack(1, 2, 3)! 
string result = foo.Quack(1, 2, 3); 

// note that it will explode with a RuntimeBinderException if there is no 
// string Quack(int, int, int) method! 

dynamic dahili yansıma kullanan ... referans verilebilir bir Foo sınıf yok. Eğer değilse, bazı sağlıklı çalışma kontrolü,

object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();} 
Type typeFoo = objFoo.GetType(); // You should check for null values before! 
MethodInfo mi = type.GetMethod("Quack"); // You should check if the Quack method 
             // exists 
string result = (string)mi.Invoke(objFoo, new object[] { 1, 2, 3 }); 

ya: durumunda 4 olarak, ancak doğrudan yansıma kullanarak: Sen Quack yöntemini almak ve

Vaka 5 diyoruz doğrudan yansıması kullanabilirsiniz emin foo doğru Quack edebilirsiniz:

MethodInfo mi = type.GetMethod("Quack", 
        BindingFlags.Instance | BindingFlags.Public, 
        null, 
        new[] { typeof(int), typeof(int), typeof(int) }, 
        null); 

if (mi != null && typeof(string).IsAssignableFrom(mi.ReturnType)) 
{ 
    string result = (string)mi.Invoke(objFoo, new object[] { 1, 2, 3 }); 
} 

Vaka -Infinity: tip Foo sana tamamen yabancı olan r programı. Başvurulan bir Foo sınıfınız yok. IFoo arayüzünüz yok. Bir Foo'un ne olduğunu bile bilmiyorsunuz, bunun sadece bir sınıf olduğunu biliyorsunuz (ya da belki de bir kutucuktur struct, ama sizin bakış açınızdan değişmiyor ... Bu bir interface olamaz çünkü Sonunda her/struct her bir interface'un arkasında bir beton olmalıdır. Yöntemlerini, alanlarını ve özelliklerini bilmiyorsunuz (çünkü Foo'un ne olduğunu bilmiyorsunuz).

Bu bilinmeyen sınıfa bir object ekleyebilseniz bile ne yapabilirsiniz?yerde eğer vardı çünkü bir parametre/dönüş değeri olarak kabul Kodunuzdaki yöntemleri olamaz:

int INeedFoo(Foo par) { return 0; } 

sonra açıkça Foo tanırdık. .NET kitaplığı, bir parametre/dönüş değeri olarak kabul eden yöntemlere sahip olamaz, çünkü sahip olsaydı, Foo'u bilirsiniz. Yapabileceğiniz

tek şey parametre olarak Foo kabul Eğer yansıma yoluyla keşfetmek diğer bazı yöntemlere geçmek olduğunu ... Ama Invoke yöntem parametreleri olarak object dizisi kabul eder ... Sen gerekmez object'u Invoke numaralı telefondan aramak için! Sadece diziye koymanız gerekiyor.

+0

Soruya aşırı yüklendim :-) – user2341923

+0

@XyiTebe Üç vakadan hangisinin ilgilendiğini söyle – xanatos

+0

İlgilendiğim konu dinamik olanıdır. çalışma zamanında bilinir. – user2341923

1

Bu eşdeğer olacaktır:

object objFoo = MakeFoo(); 
Foo result = (Foo)objFoo; 

derleme zamanında bilinmeyen olan bir türe bir nesne döküm hiçbir gerçek anlamı yok - Bunu kullanmak mümkün olmayacaktır:

object objFoo = MakeFoo(); 
UnkownType result = (UknownType)objFoo; 

UknownType'un ne olduğunu bilmiyorsanız, yansıma veya dinamiklere başvurmadan yöntemlerinden hiçbirini kullanamazsınız.