实现具有类型约束的通用接口

Posted

技术标签:

【中文标题】实现具有类型约束的通用接口【英文标题】:implementing a generic interface with type constraints 【发布时间】:2011-06-21 16:14:04 【问题描述】:

我有一个 Visual Studio 2008 C# 2.0 CF 项目,我正在其中实现一个通用接口 IComparison。可以调用IComparison.Compare 方法来执行任何类型的对指定对象有效的比较,因此我不想对其施加类型约束。

public interface IComparison<EXPECTED_PARAM>

    Result Compare<RETURNED_PARAM>(RETURNED_PARAM returned);

但是,实现可以更具体。在这种情况下,我想说给GreaterThan.Compare的参数可以与System.IComparable在构造函数中给定的EXPECTED_PARAM进行比较。

public class GreaterThan<EXPECTED_PARAM> : IComparison<EXPECTED_PARAM>

    private EXPECTED_PARAM expected_;

    public GreaterThan(EXPECTED_PARAM expected)
    
        expected_ = expected;
    

    public Result Compare<RETURNED_PARAM>(RETURNED_PARAM returned) 
        where RETURNED_PARAM : IComparable< EXPECTED_PARAM >
    
        return ((returned == null && expected_ == null) ||
                (returned != null && returned.CompareTo( expected_ ) > 0)) ?
               Result.Fail : Result.Pass;
    

不幸的是,这给了我错误:

error CS0460: Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly

我需要做什么才能对EXPECTED_PARAM 对象与RETURNED_PARAM 对象进行任意比较?

谢谢, 保罗H

【问题讨论】:

【参考方案1】:

这个怎么样?

    public interface IComparison<EXPECTED_PARAM, RETURNED_PARAM>

    Result Compare(RETURNED_PARAM returned);


public class GreaterThan<EXPECTED_PARAM, RETURNED_PARAM> : IComparison<EXPECTED_PARAM, RETURNED_PARAM> where RETURNED_PARAM : IComparable<EXPECTED_PARAM>

    private EXPECTED_PARAM expected_;      
    public GreaterThan(EXPECTED_PARAM expected)     
             expected_ = expected;           

    public Result Compare(RETURNED_PARAM returned)          
    
        return ((returned == null && expected_ == null) || 
            (returned != null && returned.CompareTo( expected_ ) > 0)) ?                
            Result.Fail : Result.Pass;
    
 

【讨论】:

这可能是我必须要做的。我唯一不喜欢的是,在之前调用了Compare 之前,我不必知道RETURNED_PARAM 类型。为此,我必须在施工时了解这两种类型。谢谢!【参考方案2】:

您的继承层次是问题所在。 GreaterThan 继承自 IComparison&lt;EXPECTED_PARAM&gt;,这意味着您告诉编译器它实现了 Compare&lt;EXPECTED_PARAM&gt;,但您希望它实现 Compare&lt;RETURNED_PARAM&gt;。您可以删除界面上的通用约束:

public interface IComparison

    Result Compare<RETURNED_PARAM>(RETURNED_PARAM returned)
    where RETURNED_PARAM : IComparable;


public class GreaterThan<EXPECTED_PARAM>: IComparison

    private EXPECTED_PARAM expected_;

    public GreaterThan(EXPECTED_PARAM expected)
    
        expected_ = expected;
    

    public Result Compare<RETURNED_PARAM>(RETURNED_PARAM returned) 
        where RETURNED_PARAM : IComparable
    
        return ((returned == null && expected_ == null) ||
                (returned != null && returned.CompareTo( expected_ ) > 0)) ?
               Result.Fail : Result.Pass;
    

【讨论】:

如果我从IComparison 接口中删除类型约束,那么我会得到error CS0460: Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly。另外,我更喜欢通用的IComparable&lt;&gt; 接口以避免装箱/拆箱。 @PaulH 我刚刚(重新)测试了我的示例代码,它可以编译。你的和我的不一样吗? 是的,它按照发布的方式编译,但您提到从IComparison.Compare 接口中删除通用约束。如果我删除那个where RETURNED_PARAM : IComparable,那么它就不会编译。

以上是关于实现具有类型约束的通用接口的主要内容,如果未能解决你的问题,请参考以下文章

如何在具有通用参数类型的接口中实现函数?

“协议......只能用作通用约束,因为它具有 Self 或关联的类型要求”是啥意思?

“协议......只能用作通用约束,因为它具有 Self 或关联的类型要求”是啥意思?

Protocol 'View' 只能用作通用约束,因为它具有 Self 或关联的类型要求

为啥我会收到错误“协议……只能用作通用约束,因为它具有自身或关联的类型要求”?

具有不满意类型约束的通用方法是隐藏扩展方法[重复]