C#cast泛型类型

时间:2012-07-24 03:27:47

标签: c# generics dynamic casting

我有一个有趣的问题,它超越了我的C#舒适区。通过使用WsdlImporter和CodeDomProvider类动态检查Web服务WSDL,我可以生成客户端代理代码并将其编译到Web服务。这包括服务客户端类,声明如下:

public partial class SomeServiceClient : System.ServiceModel.ClientBase<ISomeService>, ISomeService {...}

请注意,客户端类的名称和ISomeService合同的名称是动态的 - 我事先并不知道。我可以使用:

动态地实例化该类的对象
string serviceClientName = "SomeServiceClient";// I derive this through some processing of the WSDL
object client = webServiceAssembly.CreateInstance(serviceClientName , false, System.Reflection.BindingFlags.CreateInstance, null, new object[] { serviceEndpoint.Binding, serviceEndpoint.Address }, System.Globalization.CultureInfo.CurrentCulture, null);

但是,如果我需要在此客户端类中设置ClientCredentials,那么我无法弄清楚如何执行此操作。我以为我可以将客户端对象强制转换为System.ServiceModel.ClientBase泛型类,然后引用ClientCredentials属性。但是,以下编译但在运行时失败:

System.Net.NetworkCredential networkCredential = new System.Net.NetworkCredential(username, password, domain);
((System.ServiceModel.ClientBase<IServiceChannel>)client).ClientCredentials.Windows.ClientCredential = networkCredential;

是否有某种方法可以动态指定强制转换,或者是否有某种方法可以在没有此强制转换的情况下设置凭据?谢谢你的帮助!马丁

1 个答案:

答案 0 :(得分:2)

如果你已经分享了这个例外,我们可以为你提供更好的帮助,但我猜是这样的:

您的类层次结构如下:

public interface ISomeService : System.ServiceModel.IServiceChannel
{
    ...
}

public class SomeServiceClient : System.ServiceModel.ClientBase<ISomeService>
{
}

并且您正在尝试将SomeServiceClient投射到System.ServiceModel.ClientBase<IServiceChannel>。遗憾的是你无法做到这一点,C#4有一个名为Covariance的功能,它允许转换泛型类型的参数,但这只适用于接口,而不是具体的类。

所以其他选项是使用反射:

ClientCredentials cc = (ClientCredentials)client.GetType().GetProperty("ClientCredentials").GetValue(client,null);
cc.Windows.ClientCredential = networkCredential;

这应该没有问题(我没有测试过,所以如果它不起作用,请告诉我问题所以我可以解决它。)