Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a dynamic be used as a generic?

How can I use a dynamic as a generic?

This

var x = something not strongly typed;
callFunction<x>();

and this

dynamic x = something not strongly typed;
callFunction<x>();

both produce this error

Error   1   The type or namespace name 'x' 
could not be found (are you missing a using directive or an assembly reference?)

What can I do to x to make it legitimate enough to be used in <x>?

like image 566
Travis J Avatar asked Apr 12 '12 22:04

Travis J


2 Answers

You could use type inference to sort of trampoline the call:

dynamic x = something not strongly typed;
CallFunctionWithInference(x);

...

static void CallFunctionWithInference<T>(T ignored)
{
    CallFunction<T>();
}

static void CallFunction<T>()
{
    // This is the method we really wanted to call
}

This will determine the type argument at execution time based on the execution-time type of the value of x, using the same kind of type inference it would use if x had that as its compile-time type. The parameter is only present to make type inference work.

Note that unlike Darin, I believe this is a useful technique - in exactly the same situations where pre-dynamic you'd end up calling the generic method with reflection. You can make this one part of the code dynamic, but keep the rest of the code (from the generic type on downwards) type-safe. It allows one step to be dynamic - just the single bit where you don't know the type.

like image 126
Jon Skeet Avatar answered Sep 30 '22 09:09

Jon Skeet


It's hard to tell what exactly are you trying to do. But if you want to call a generic method with a type parameter that is the same as some object, you can't do that directly. But you can write another method that takes your object as a parameter, let the dynamic infer the type and then call the method you want:

void HelperMethod<T>(T obj)
{
    CallFunction<T>();
}

…

dynamic x = …;
HelperMethod(x);
like image 24
svick Avatar answered Sep 30 '22 09:09

svick