具有接口混淆的C#通用ClientBase [英] C# generic ClientBase with interface confusion

查看:427
本文介绍了具有接口混淆的C#通用ClientBase的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆