Saturday, 15 May 2010

c# - Using reflection to create a class that implements an interface of type T -



c# - Using reflection to create a class that implements an interface of type T -

i have unusual reflection problem.

refer class fooattempt1 implements interface ifooattempt1 has property returns ianimal. in case of fooattempt1 returning dog.

in programme in question, our classes implement ifooattempt1 instantiated, work , store own reflected type , key database , later rehydrated using reflection. there many such classes implement ifooattempt1 , architecture working quite well.

you can see basic process @ work in method attempt1().

the problem that real classes more complex ifooattempt1 , easy create mistake. such have refactored code utilize generics help ensure these classes implemented correctly.

refer fooattempt2 implements generic interface ifooattempt2 < t > t : ianimal.

this ensures animal property defined

public dog animal

rather

public ianimal animal

both ifooattempt1 , ifooattempt2 functionally identical self-documenting feature of generics makes implementing our rather more complex classes simple.

the problem comes when refer attempt2() code. when using reflection recreate fooattempt2 line

object o = constructor.invoke(null); ifooattempt2<ianimal> foo2 = (ifooattempt2<ianimal>) o;

displays error

an unhandled exception of type 'system.invalidcastexception' occurred in consoleapplication1.exe additional information: unable cast object of type 'consoleapplication1.fooattempt2' type 'consoleapplication1.ifooattempt2`1 [consoleapplication1.ianimal]'.

i can understand point how do using reflection?

in immediate window, if go

? o {consoleapplication1.fooattempt2} animal: {consoleapplication1.dog}

so has reflected correctly. can't cast (ifooattempt2<ianimal>) though fooattempt2 defined ifooattempt2<dog> dog ianimal.

my immediate thought seek this

type type = assembly.gettype(classname, false, true).makegenerictype(new[] { typeof(ianimal) });

but not compile. evidently compiler not typeof(interface)

at stage totally stuck.

thanks!

class programme { static void main(string[] args) { attempt1(); attempt2(); } static void attempt1() { fooattempt1 foo = new fooattempt1(); console.writeline(foo.animal.makenoise()); string classname = foo.gettype().fullname; // ----- // assembly assembly assembly = typeof(fooattempt1).assembly; // class type type = assembly.gettype(classname, false, true); // create instance constructorinfo constructor = type.getconstructor(new type[] { }); ifooattempt1 foo2 = (ifooattempt1)constructor.invoke(null); console.writeline(foo2.animal.makenoise()); } static void attempt2() { fooattempt2 foo = new fooattempt2(); console.writeline(foo.animal.makenoise()); string classname = foo.gettype().fullname; // ----- // assembly assembly assembly = typeof(fooattempt2).assembly; // class type type = assembly.gettype(classname, false, true); // create instance constructorinfo constructor = type.getconstructor(new type[] { }); object o = constructor.invoke(null); ifooattempt2<ianimal> foo2 = (ifooattempt2<ianimal>) o; // << problem here console.writeline(foo2.animal.makenoise()); } } public interface ianimal { string makenoise(); } public class dog : ianimal { public string makenoise() { homecoming "bark"; } } public interface ifooattempt1 { ianimal animal { get; } } public class fooattempt1 : ifooattempt1 { public fooattempt1() { } public ianimal animal { { homecoming new dog(); } } } public interface ifooattempt2<t> t : ianimal { t animal { get; } } public class fooattempt2 : ifooattempt2<dog> { public fooattempt2() { } public dog animal { { homecoming new dog(); } } }

you can create ifooattempt2 covariant in t:

public interface ifooattempt2<out t> t : ianimal { t animal { get; } }

then cast ifooattempt2<ianimal> succeed.

c# generics reflection

No comments:

Post a Comment