ClientBase的C#定义是:

public abstract class ClientBase<TChannel> : ICommunicationObject,
    IDisposable
where TChannel : class

这清楚地表明了class类型对TChannel的约束。据我所知,这意味着您在声明自己的类时不能使用泛型和接口(interface)类型。因此,给定这样声明的服务:
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约束将通用类型约束为引用类型。根据定义,接口(interface)是引用类型。您不能做的是使用值类型作为泛型类型:ClientBase<int>将是编译时错误。

至于第二个错误,您并没有约束TInterface,然后在ClientBase<TInterface>中使用它。因为ClientBase将其通用类型约束为引用类型(class),所以您需要相应地约束TInterface

关于带有接口(interface)困惑的C#通用ClientBase,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40949583/

10-09 00:32