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