【问题标题】:C# generic ClientBase with interface confusion具有接口混淆的 C# 通用 ClientBase
【发布时间】: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&lt;int&gt; 将是编译时错误。
  • @InBetween,该死,这就是我不理解的关键......如果你想让这个评论成为答案,我会接受它。

标签: c# wcf generics


【解决方案1】:

class 约束将泛型类型限制为引用类型。根据定义,接口是引用类型。您不能将值类型用作泛型类型:ClientBase&lt;int&gt; 将是编译时错误。

至于第二个错误,你没有限制TInterface然后在ClientBase&lt;TInterface&gt;中使用它。因为ClientBase 将其泛型类型限制为引用类型(class),所以您需要相应地限制TInterface

【讨论】:

    猜你喜欢
    • 2021-09-20
    • 2016-07-18
    • 1970-01-01
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 2017-10-25
    • 2013-08-29
    • 1970-01-01
    相关资源
    最近更新 更多