Reputation: 6270
I have an interface:
public interface IOut<T>
{
void Get(out T output);
}
and a class that implements it:
public class Impl : IOut<string>, IOut<int>{
public void Get(out string output) { output = "string"; }
public void Get(out int output) { output = 12; }
}
I can do the following just fine:
public static void Main()
{
dynamic dImpl = new Impl();
string sOutput;
int iOutput;
dImpl.Get(out sOutput);
dImpl.Get(out iOutput);
Console.WriteLine(sOutput);
Console.WriteLine(iOutput);
}
My problem is that I only know the type I need to get at runtime, so how I want to call my Get
code is like so:
public static void Main()
{
dynamic dImpl = new Impl();
var t = typeof(string);
t output;
dImpl.Get(out output);
Console.WriteLine(output);
}
Now, I know this won't work, and I've tried reflectively performing a Cast:
public static T Cast<T>(object o) { return (T) o; }
but I don't have an object to cast, I only have a Type
. I've tried Defaults:
public static T Default<T>() { return default(T); }
but the default for things like string
etc is null, and when invoking the method via reflection:
var method = typeof(Program).GetMethod("Default").MakeGenericMethod(typeof(string));
var defaulted = method.Invoke(null, null);
defaulted
is going to be null, and when calling dImpl.Get(out defaulted)
the runtime is unsure of which overload to use.
So, what I'm looking for is either: a) someway to do this using the current interface setup [preferred] b) a different way to achieve the goals
Upvotes: 0
Views: 136
Reputation: 144136
You can get the method to invoke from the interface type instead of the implementing type:
object[] parameters = new object[] { null };
Type typeParam = typeof(string);
Type ifaceType = typeof(IOut<>).MakeGenericType(typeParam);
MethodInfo method = ifaceType.GetMethod("Get");
var impl = new Impl();
method.Invoke(impl, parameters);
object outParam = parameters[0];
Upvotes: 2
Reputation: 24383
If you don't know the type of output
until runtime, you can't declare a strongly-typed instance of it in C#.
If you can make the calling logic ( Main
in your example ) generic on T
too, that would work - but this only defers your problem.
The other option is to declare output
as a base class or interface and restrict the generic T
to that. Using object
as the base class might work for you - depends on what you want to do with it.
Upvotes: 0