通过使用变量名称调用接口
问题描述:
我在变量中分配接口名称,通过该变量,我需要调用接口,即在ChannelFactory类中只接受接口。如果我直接在ChannelFactory中将接口指定为Test,那么它工作正常。通过使用变量名称调用接口
string interfaceName = "Test";
var factory = new ChannelFactory<**interfaceName**>(new BasicHttpBinding(), new EndpointAddress(*********));
请建议可能的方式,如何从字符串变量类型转换为接口。
答
首先:你不能那样做! 您的代码行
var factory = new ChannelFactory<interfaceName>(new BasicHttpBinding(), new EndpointAddress(***));
可能表明工厂(var
型)是变种,但事实并非如此。它是一个变量,它是类型安全的,由编译器制作,由于通用调用new ChannelFactory<interfaceName>
。所以你不能在泛型调用中指定一个变量接口。
答
您不能直接从字符串变量转换为接口。但是,您可以使用反射来创建通用类型。
注意然而,所得到的工厂将是类型的对象,所以要求它所有的接口方法也将必须完成槽反射(或使用dynamic keyword)
下面的代码将创建的ChannelFactory槽式反射,但正如你所看到的结果是一个类型的对象,这意味着你不能直接调用就可以了通道的方法。
string interfaceName = "StackOverflow.ITest";
Type f = typeof (ChannelFactory<>);
Type[] typeargs = {Type.GetType(interfaceName, true)};
Type constructed = f.MakeGenericType(typeargs);
object factory = Activator.CreateInstance(constructed);
答
你不能传递接口名作为通用约束字符串。你可以做下面的
string interfaceName = "Test";
Type myInterfaceType = Type.GetType(interfaceName);
var factoryType = typeof(ChannelFactory<>).MakeGenericType(myInterfaceType);
var factoryCtr = factoryType.GetConstructor(new []{ typeof(Binding), typeof(EndpointAddress)});
ChannelFactory factory = factoryCtr.Invoke(new object[]{ new BasicHttpBinding(), new EndpointAddress("")}) as ChannelFactory;
答
接下来从费舍尔曼的答案,第二,你不能这样做,要么!
一般类型的类型参数列表(尖括号中的类型名称;例如,在List<int>
“INT”)不是变量。它们是静态编译时令牌。你可以不这样做比你试图做什么:
string className = "FileInfo";
**className** theObject = new **className**("C:\\autoexec.bat");
因为C#是一种静态类型语言,类型,名称标记表示的类型必须在编译时静态闻名。请注意,这里基于反射的答案会为您提供一个参考,其静态类型是ChannelFactory<TChannel>
的子类型,可以是非泛型ChannelFactory
或object
。对于仅在运行时才知道的类型,不能有静态编译时引用。
尽管通过将最后一行更改为'var factory = Activator.CreateInstance(构造)为ChannelFactory;'您在IDE中保留了一些基本的通道功能。 – flindeberg 2012-02-06 14:59:30