【发布时间】:2016-12-03 15:50:01
【问题描述】:
ClientBase 的 C# 定义为:
public abstract class ClientBase<TChannel> : ICommunicationObject,
IDisposable
where TChannel : class
这清楚地表明了TChannel 类型上的class 约束。据我所知,这意味着您在声明自己的类时不能使用泛型的接口类型。所以给定一个这样声明的服务:
public IMyService
...
public MyService : IMyService
...
这应该可行:
public MyServiceClient : ClientBase<MyService>
这应该不:
public MyServiceClient : ClientBase<IMyService>
但显然我不明白,因为该示例显示了以下声明:
public partial class SampleServiceClient :
System.ServiceModel.ClientBase<ISampleService>, ISampleService
更重要的是,我正在尝试抽象身份验证,并使用实用方法正确关闭客户端:
public TResult WithClient<TInterface, T, TResult>(T service,
Func<TInterface, TResult> callback)
where T : ClientBase<TInterface>, TInterface
{
service.ClientCredentials.UserName.UserName = userName;
service.ClientCredentials.UserName.Password = password;
try
{
var result = callback(service);
service.Close();
return result;
}
catch (Exception unknown)
{
service.Abort();
throw unknown;
}
}
但这给了我编译器错误:
The type 'TInterface' must be a reference type in order to use it as parameter 'TChannel' in the generic type or method 'ClientBase<TChannel>'
有人能解开这里的困惑吗?我做错了什么?
---- 更新----
根据@InBetween,解决方案是将where TInterface : class 约束添加到我的实用程序方法中:
public TResult WithClient<TInterface, T, TResult>(T service,
Func<TInterface, TResult> callback)
where TInterface : class
where T : ClientBase<TInterface>, TInterface
{
service.ClientCredentials.UserName.UserName = userName;
service.ClientCredentials.UserName.Password = password;
try
{
var result = callback(service);
service.Close();
return result;
}
catch (Exception unknown)
{
service.Abort();
throw unknown;
}
}
【问题讨论】:
-
class约束将泛型类型限制为引用类型。根据定义,接口是引用类型。您不能做的是使用值类型作为泛型类型:ClientBase<int>将是编译时错误。 -
@InBetween,该死,这就是我不理解的关键......如果你想让这个评论成为答案,我会接受它。