具有接口混淆的C#通用ClientBase [英] C# generic ClientBase with interface confusion
问题描述
ClientBase 是:
public abstract class ClientBase< TChannel> :ICommunicationObject,
IDisposable
其中TChannel:class
这清楚地表明 class
对 TChannel
类型的约束。据我所知,这意味着在声明自己的类时,不能 和泛型接口类型。所以给一个这样声明的服务:
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)
其中T:ClientBase< TInterface> ;,TInterface
{
service.ClientCredentials.UserName.UserName = userName;
service.ClientCredentials.UserName.Password = password;
尝试
{
var result = callback(service);
service.Close();
返回结果;
}
catch(例外不明)
{
service.Abort();
抛出未知;
但是这给了我编译错误:
类型'TInterface'必须是一个引用类型,以便将其用作泛型类型或方法'ClientBase< TChannel>'
有人可以在此澄清混淆吗?我做错了什么?
---- UPDATE ----
Per @InBetween,解决方法是将TInterface:class 约束中的添加到我的实用程序方法中:
<$ p (t服务,
Func< TInterface,TResult>回调)
其中TInterface:class
其中T:表示T接口,T,TResult> ClientBase< TInterface>,TInterface
{
service.ClientCredentials.UserName.UserName = userName;
service.ClientCredentials.UserName.Password = password;
尝试
{
var result = callback(service);
service.Close();
返回结果;
}
catch(例外不明)
{
service.Abort();
抛出未知;
}
}
class
约束将通用类型约束为引用类型。根据定义,接口是引用类型。你不能做的就是使用一个值类型作为泛型类型: ClientBase< int>
会是一个编译时错误。
至于第二个错误,您不是限制 TInterface
,然后在 ClientBase< TInterface>
。由于 ClientBase
将其泛型限制为引用类型( class
),因此您需要约束 TInterface
据此。
The C# definition of ClientBase is:
public abstract class ClientBase<TChannel> : ICommunicationObject,
IDisposable
where TChannel : class
Which clearly indicates the class
constraint on the TChannel
type. To the best of my knowledge, that means that you cannot use and interface type for the generic when declaring your own class. So given a service declared thusly:
public IMyService
...
public MyService : IMyService
...
This should work:
public MyServiceClient : ClientBase<MyService>
This should NOT:
public MyServiceClient : ClientBase<IMyService>
But clearly I am not understanding because the example shows a declaration of:
public partial class SampleServiceClient :
System.ServiceModel.ClientBase<ISampleService>, ISampleService
And more to the point, I am trying to abstract the authentication, and proper closing of the client with a utility method:
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;
}
}
But this gives me the compiler error:
The type 'TInterface' must be a reference type in order to use it as parameter 'TChannel' in the generic type or method 'ClientBase<TChannel>'
Can somebody clear the confusion here? What am I doing wrong?
---- UPDATE ----
Per @InBetween, the resolution is to add the where TInterface : class
constraint to my utility method:
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;
}
}
The class
constraint constraints the generic type to a reference type. An interface is, by definition, a reference type. What you can't do is use a value type as the generic type: ClientBase<int>
would be a compile time error.
As to the second error, you are not constraining TInterface
and then using it inClientBase<TInterface>
. Because ClientBase
constraints its generic type to reference types (class
), you need to constraint TInterface
accordingly.
这篇关于具有接口混淆的C#通用ClientBase的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!