c# - A Generic Pass-Through Interface. Is this possible? -


what wouldn't give have work:

public interface icallback {     void handle<t>(t arg); }  public class messagehandler : icallback {     public void handle<t>(t arg)     {         string name = typeof(t).name;         console.writeline(name);     }      public void handle(int arg)     {         string name = "wow, int";         console.writeline(name);     } }  public class worker {     public void dosomething(icallback cb)     {         cb.handle(55);     } }  //... worker foo = new worker(); icallback boo = new messagehandler();  //i want print "wow, int" foo.dosomething(boo) 

unfortunately, calls generic entry point rather "specialized" entry point. well, thats interfaces you.

i've tried same approach replacing int-specific signature generic signature mojo specific:

public void handle<t>(t arg) t : mojo {} 

i hoping sufficient form "special override" if argument of type mojo. compiler complains have 2 methods same signature (one mojo specific, other open-ended). well, hoping think "the same signature" both fulfill interface , "best" selected @ run-time. ah well.

in effect, i'm trying achieve vaguely similar "traits," "else-if-then of c++". guess considered form of "interface signature contravariance."

i'd love discover there special c# keyword enables capability, or featured addition c# in .net 4.5.

yes, no? comments?

try changing worker class this:

public class worker {     public void dosomething(icallback cb)     {         ((dynamic)cb).handle(55);     } } 

[edit]

just know, adding innocuous-looking "dynamic" severely changes output code. invokes compiler @ run-time dynamic thing.

i draw attention comments , other answers here. recommend read them , understand why doing above might not such great idea.

further, noted in answer below, constraining argument type icallback will still allow runtime errors if handle() method implemented explicitly.

here's il simple-looking method:

.method public hidebysig instance void dosomething(class consoleapplication1.icallback cb) cil managed {     .maxstack 9     .locals init (         [0] class [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfo[] cs$0$0000)     l_0000: nop      l_0001: ldsfld class [system.core]system.runtime.compilerservices.callsite`1<class [mscorlib]system.action`3<class [system.core]system.runtime.compilerservices.callsite, object, int32>> consoleapplication1.worker/<dosomething>o__sitecontainer0::<>p__site1     l_0006: brtrue l_0058     l_000b: ldc.i4 256     l_0010: ldstr "handle"     l_0015: ldnull      l_0016: ldtoken consoleapplication1.worker     l_001b: call class [mscorlib]system.type [mscorlib]system.type::gettypefromhandle(valuetype [mscorlib]system.runtimetypehandle)     l_0020: ldc.i4.2      l_0021: newarr [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfo     l_0026: stloc.0      l_0027: ldloc.0      l_0028: ldc.i4.0      l_0029: ldc.i4.0      l_002a: ldnull      l_002b: call class [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfo [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfo::create(valuetype [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfoflags, string)     l_0030: stelem.any [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfo     l_0035: ldloc.0      l_0036: ldc.i4.1      l_0037: ldc.i4.3      l_0038: ldnull      l_0039: call class [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfo [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfo::create(valuetype [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfoflags, string)     l_003e: stelem.any [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfo     l_0043: ldloc.0      l_0044: call class [system.core]system.runtime.compilerservices.callsitebinder [microsoft.csharp]microsoft.csharp.runtimebinder.binder::invokemember(valuetype [microsoft.csharp]microsoft.csharp.runtimebinder.csharpbinderflags, string, class [mscorlib]system.collections.generic.ienumerable`1<class [mscorlib]system.type>, class [mscorlib]system.type, class [mscorlib]system.collections.generic.ienumerable`1<class [microsoft.csharp]microsoft.csharp.runtimebinder.csharpargumentinfo>)     l_0049: call class [system.core]system.runtime.compilerservices.callsite`1<!0> [system.core]system.runtime.compilerservices.callsite`1<class [mscorlib]system.action`3<class [system.core]system.runtime.compilerservices.callsite, object, int32>>::create(class [system.core]system.runtime.compilerservices.callsitebinder)     l_004e: stsfld class [system.core]system.runtime.compilerservices.callsite`1<class [mscorlib]system.action`3<class [system.core]system.runtime.compilerservices.callsite, object, int32>> consoleapplication1.worker/<dosomething>o__sitecontainer0::<>p__site1     l_0053: br l_0058     l_0058: ldsfld class [system.core]system.runtime.compilerservices.callsite`1<class [mscorlib]system.action`3<class [system.core]system.runtime.compilerservices.callsite, object, int32>> consoleapplication1.worker/<dosomething>o__sitecontainer0::<>p__site1     l_005d: ldfld !0 [system.core]system.runtime.compilerservices.callsite`1<class [mscorlib]system.action`3<class [system.core]system.runtime.compilerservices.callsite, object, int32>>::target     l_0062: ldsfld class [system.core]system.runtime.compilerservices.callsite`1<class [mscorlib]system.action`3<class [system.core]system.runtime.compilerservices.callsite, object, int32>> consoleapplication1.worker/<dosomething>o__sitecontainer0::<>p__site1     l_0067: ldarg.1      l_0068: ldc.i4.s 12     l_006a: callvirt instance void [mscorlib]system.action`3<class [system.core]system.runtime.compilerservices.callsite, object, int32>::invoke(!0, !1, !2)     l_006f: nop      l_0070: ret  } 

Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -