2

In the example bellow, is it possible to set the Classname type parameter dynamically?

UpdateAndSave<Classname>>().Execute(sql)
tereško
  • 58,060
  • 25
  • 98
  • 150
MikeAlike234
  • 759
  • 2
  • 12
  • 29
  • 3
    There's a very cute trick for this if the method takes an instance as a parameter; if this was `UpdateAndSave(T theObject)`, it would be pretty trivial - *even if you don't know the object type* (i.e. the caller just knows `object theObject`). – Marc Gravell Nov 07 '13 at 11:27
  • Sadly you have to write messy reflection code to achieve this as the language cannot natively support it. – David Arno Nov 07 '13 at 11:37
  • @DavidArno the language *comes very close* though (see answer) – Marc Gravell Nov 07 '13 at 11:47
  • 1
    @MarcGravell You sir are evil! :) – David Arno Nov 07 '13 at 11:49

2 Answers2

7

If your type is coming from an object, then you can cheat using dynamic - hijacking it to perform (and cache, via meta-programming etc) the type resolution for you. For example - if you currently have:

object obj = ...
Type type = obj.GetType();
// now want to call UpdateAndSave<type>(...)

then you can do:

public void Voodoo<T>(T obj, string sql) {
    UpdateAndSave<T>().Execute(sql);
}

and just:

object obj = ...
Voodoo((dynamic)obj, sql);

The runtime will detect the type of obj, determine the best overload to use (which will be Voodoo<TheActualType>(...)), and call that. Plus it will cache the strategy for that type, so it is fast next time (it only does any significant work once per unique type).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
4

Well you can call it by reflection, yes - using MethodInfo.MakeGenericMethod to provide the type arguments:

var method = typeof(Whatever).GetMethod("UpdateAndSave");
var genericMethod = method.MakeGenericMethod(typeArgument);
genericMethod.Invoke(target, new object[] { sql });
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Do you prefer this over [Marc's Answer](http://stackoverflow.com/a/19835099/18192)? – Brian Nov 07 '13 at 22:26
  • @Brian: That's assuming you've got an object - if you've *just* got a type, it won't work. But both are viable. – Jon Skeet Nov 07 '13 at 22:29