Клиентские классы WCF обычно настраиваются следующим образом:
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;
}
Thisэто один из сценариев, где он мне подходит, так как я не забочусь , что такое TChannel - я не собираюсь использовать его в своем коде, я просто хочу использовать любую ClientBase <>в качестве ограничения.
С учетом сказанного может кто-нибудь придуматьс творческим способом реализовать мое свободное владение без спецификации типов?
Имейте в виду, что если вы не вернете переданный исходный элемент, вы потеряете способность вызывать методы обслуживания, реализованные в IService.