输出类型仅在运行时已知的泛型参数

本文关键字:泛型 参数 运行时 类型 输出 | 更新日期: 2023-09-27 18:02:45

有一个接口:

public interface IOut<T>
{
    void Get(out T output);
}

和实现它的类:

public class Impl : IOut<string>, IOut<int>{
    public void Get(out string output) { output = "string"; }
    public void Get(out int output) { output = 12; }
}

我可以这样做:

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);
}

我的问题是,我只知道在运行时我需要获取的类型,所以我希望如何调用我的Get代码是这样的:

public static void Main()
{
    dynamic dImpl = new Impl();
    var t = typeof(string);
    t output;
    dImpl.Get(out output);
    Console.WriteLine(output);
}

现在,我知道这个不会起作用,我已经尝试了反射性地执行Cast:

public static T Cast<T>(object o) { return (T) o; }

但是我没有对象要强制转换,我只有一个Type。默认值:

public static T Default<T>() { return default(T); }

,但默认的东西,如string等是空的,当调用方法通过反射:

var method = typeof(Program).GetMethod("Default").MakeGenericMethod(typeof(string));
var defaulted = method.Invoke(null, null);

defaulted将为空,当调用dImpl.Get(out defaulted)时,运行时不确定使用哪个过载。

所以,我要找的是:A)以某种方式使用当前的接口设置来做到这一点[首选]B)实现目标的不同方式

输出类型仅在运行时已知的泛型参数

您可以从接口类型而不是实现类型中获得要调用的方法:

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];

如果你在运行时才知道output的类型,你就不能在c#中声明它的强类型实例。

如果你可以使调用逻辑(Main在你的例子中)在T上也是通用的,那将工作-但这只是推迟你的问题。

另一个选择是将output声明为基类或接口,并将泛型T限制为基类或接口。使用object作为基类可能对你有用——这取决于你想用它做什么。