输出只有在运行时才知道的类型的泛型参数

时间:2013-03-06 12:32:02

标签: c# generics dynamic

我有一个界面:

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

现在,我知道不会工作,我已经尝试过反思性地执行演员:

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

但是我没有要投射的对象,我只有Type。我尝试过默认值:

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

string等内容的默认值为null,并且在通过反射调用方法时:

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

defaulted将为null,并且在调用dImpl.Get(out defaulted)时,运行时不确定要使用哪个重载。

所以,我正在寻找的是: a)使用当前界面设置[首选]来执行此操作 b)实现目标的不同方式

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

如果在运行时之前不知道output的类型,则无法在C#中声明它的强类型实例。

如果您可以在Main上制作调用逻辑(在您的示例中为T),那么这样就可以了 - 但这只会延迟您的问题。

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