[英]C# Passing generics argument type at runtime
在我的应用程序中,我有使用输入和输出相互链接的组件。 将要交换的数据可以是任何类型,因此我使用泛型。
public interface IInputVariable<T>
{
IOutputVariable<T> Source { get; set; }
}
public interface IOutputVariable<T>
{
T Value { get; set; }
}
在另一个类中,组件链接在一起。 链接了哪些组件,是从文件派生的。 进行链接的类不知道输入和输出交换的类型。 该类只想使用以下代码连接它们:
IOutputVariable<double> output;
Type argumentType = output.GetType().GetGenericArguments()[0];
IInputVariable<argumentType> input = new BasicInputVariable<argumentType>();
input.Source = output;
此代码无法编译,因为argumentType不能用作通用参数。 有没有正确的方法来制定这个? 或者是否可以在不知道其参数类型的情况下声明泛型变量?
设置Source
属性的最简单方法是在BasicInputVariable<T>
中创建counstructor,它接受IOutputVariable<T>
:
public BasicInputVariable(IOutputVariable<T> source)
{
Source = source;
}
然后你可以轻松实例化它:
IOutputVariable<double> output;
Type argumentType = output.GetType().GetGenericArguments()[0];
object input = Activator.CreateInstance(typeof(BasicInputVariable<>)
.MakeGenericType(argumentType), output);
另一种方法是创建和实现可以提供Source
属性的接口:
public interface ISetSource
{
object Source { get; set; }
}
public class BasicInputVariable<T> : IInputVariable<T>, ISetSource
{
public IOutputVariable<T> Source { get; set; }
object ISetSource.Source
{
get { return Source; }
set { Source = (IOutputVariable<T>) value; }
}
}
现在您可以访问Source
属性:
IOutputVariable<double> output;
var input = (ISetSource) Activator.CreateInstance(typeof (BasicInputVariable<>)
.MakeGenericType(argumentType));
input.Source = output;
输入/输出泛型参数可能更安全,但不幸的是我们不能将它们与值类型一起使用......
警告:这真是丑陋的黑客,不推荐..
如果你有.NET 4.0:
IOutputVariable<double> output = something;
dynamic input = Activator
.CreateInstance(typeof(BasicInputVariable<>)
.MakeGenericType(output
.GetType()
.GetGenericArguments()[0]));
//or may be:
//dynamic input = typeof(BasicInputVariable<>)
// .MakeGenericType(output
// .GetType()
// .GetGenericArguments()[0])
// .GetConstructor(new Type[0])
// .Invoke(new object[0]);
input.Source = output;
但是我不明白是什么阻止你将类型参数double
本身直接传递给BasicInputVariable
构造函数?
IOutputVariable<double> output = something;
IInputVariable<double> input = new BasicInputVariable<double>();
input.Source = output;
如果类型参数可以是任何东西,那么为什么不使整个方法通用? 也许:
void Method<T>()
{
IOutputVariable<T> output = something;
IInputVariable<T> input = new BasicInputVariable<T>();
input.Source = output;
}
这是有效的,因为输入和输出变量的T
都相同。
如果没有更多细节,很难想出更好的解决方案,但是你应该首先重新考虑你的设计。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.