c# - How to invoke a generic method with weak-typed parameter -


i've got generic interface , bunch of classes implement it. here simplified example:

interface iprinter<in t> {     void print(t args); }  class intprinter : iprinter<int> {     public void print(int args)     {         console.writeline("this int: " +args);     } }  class stringprinter : iprinter<string> {     public void print(string args)     {         console.writeline("this string: " + args);     } } 

i have dictionary of classes generic argument's type key (i use reflection populate it):

private readonly dictionary<type, object> printers      = new dictionary<type, object>         {             {typeof (int), new intprinter()},             {typeof (string), new stringprinter()}         }; 

now recive instance of list<object> input, contains bunch of parameters of arbitrary type. each parameter want pick object, implement appropriate interface , call print method. not sure how implement that.

var args = new list<object> {1, "2"}; foreach (var arg in args) {     var printer = printers[arg.gettype()];     //how implement method calls ((iprinter<t>)printer).print((t)arg)?     print(printer, arg);  } 

i have tried

  1. reflection. works, well... reflection. looking other ways it.

    private void print(object printer, object arg) {     printer.gettype().getmethod("print").invoke(printer, new[] {arg}); } 
  2. dynamic. lot cleaner reflection , faster. reason throws exception if use type, private relative executing assembly. known limitation of dynamic objects?

    private void print(dynamic printer, dynamic arg) {     printer.print(arg); } 
  3. delegate. trying use createdelegate method create kind of weak-typed delegate methodinfo failed @ that. possible?

you might know method signature: void genericmethod<t>(t arg) translated like: void __genericmethod(type typearg1, object argument) after first call class type argument (for structures you'll generate 1 each struct).

think it. why need generics @ all? why not have:

interface iprinter {     void print(object args); } 

or even...

interface ianything {     void do(object args); } 

the answer is: compile-time feature of c# - type-safety. need avoid combining not compatible components accidentally. don't want intprinter receive string somehow. lucky if you'll exception, if not?

so, using feature , helps detect error @ compile-time. doing collecting printers dictionary? you're loosing type-safety. if you'll make mistake types somewhere, you'll experience exception or strange behaviour of program @ runtime.

i propose 2 alternatives:

  • make iprinter not type safe
  • keep generic, don't loose type-safety while using it

Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -