[英]Out generic parameters with types only known at runtime
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: 我的问题是我只知道我需要在运行时获得的类型,所以我想如何调用我的
Get
代码是这样的:
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
. 但我没有投射的对象,我只有一个
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: 但是
string
等的默认值为null,并且在通过反射调用方法时:
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. defaulted
值为null,并且在调用dImpl.Get(out defaulted)
,运行时不确定要使用哪个重载。
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 所以,我正在寻找的是:a)使用当前的界面设置来做某事[首选] b)实现目标的不同方式
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];
If you don't know the type of output
until runtime, you can't declare a strongly-typed instance of it in C#. 如果在运行时之前不知道
output
的类型,则不能在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. 如果你也可以在
T
上使调用逻辑(在你的例子中为Main
)通用,那就行了 - 但这只会延迟你的问题。
The other option is to declare output
as a base class or interface and restrict the generic T
to that. 另一种选择是将
output
声明为基类或接口,并将泛型T
限制为该类。 Using object
as the base class might work for you - depends on what you want to do with it. 使用
object
作为基类可能对你有用 - 取决于你想用它做什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.