WCF客户端类典型地是设置这样的:C#约束通用参数用于流利的接口为T <T2> /编译器不能推断类型
public class Client : ClientBase<IService>, IService
我想这些客户端与是良好的扩展方法扩展,这样我可以声明using语句,如:
using (new Client().WithCookies(...)) {}
但是,我不能想出一个办法来维持呼叫者的原始类型,而不产生一些非常笨拙调用语法:
new Client().WithCookies<Client,IService>(...)
我不知道为什么根据我所传递的编译器不能推断T,但它不能,基于扩展方法的定义:
public static T WithCookies<T, TChannel>(this T clientBase, IEnumerable<Cookie> cookies)
where T : ClientBase<TChannel>, TChannel
where TChannel : class
{
HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
requestProperty.Headers.Add(HttpCookieHeader, string.Join("; ", cookies.Select(c => c.ToCookieString(false))));
new OperationContext(clientBase.InnerChannel).OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestProperty;
return clientBase;
}
我知道埃里克利珀在他的博客,驳回指定的一个概念,“我不关心类型参数的一般是什么”(和一般好的理由) http://blogs.msdn.com/b/ericlippert/archive/2008/05/19/a-generic-constraint-question.aspx
一个伪的实现会是这样的:
public static T WithCookies<T>(this T clientBase, IEnumerable<Cookie> cookies)
where T : ClientBase<>
{
HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
requestProperty.Headers.Add(HttpCookieHeader, string.Join("; ", cookies.Select(c => c.ToCookieString(false))));
new OperationContext(clientBase.InnerChannel).OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestProperty;
return clientBase;
}
这是我认为合适的一种情况,因为我不知道护理 TChannel是什么 - 我不打算在我的代码中使用它,我只想使用任何ClientBase < >作为约束。这样说,任何人都可以想出一个创造性的方式来实现我的Fluent需求,而不需要指定类型?
请记住,如果您没有返回传入的原始项目,您将失去调用在IService中实现的服务方法的能力。
这不会给我买在这种情况下任何东西。然后对方法没有通用约束,我可以将.WithCookies()应用于不属于它的实例。 TChannel基本上与我的需求无关。任何ClientBase <>都可以接受。 – 2011-01-07 19:48:33
我完全同意这个问题,为什么编译器无法推断 - 我很茫然。 Eric Lippert在你需要他的时候在哪里? – 2011-01-07 19:49:28