无法比较通用值

Ste*_* H. 5 .net c# generics

我正在创建一个通用类来保存小部件,我在实现contains方法时遇到问题:

public class WidgetBox<A,B,C>
{
    public bool ContainsB(B b)
    {
        // Iterating thru a collection of B's
        if( b == iteratorB )  // Compiler error.
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

错误:运算符'=='无法应用于'V'和'V'类型的操作数

如果我无法比较类型,我如何实现包含?字典,列表和所有其他通用容器如何做到这一点?

jas*_*son 7

你有几个选择

首先是使用Object.Equals:

if(b.Equals(iteratorB)) {
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

小心使用此选项; if B不覆盖,Object.Equals则默认比较是引用相等,当B为引用类型时,值相等B则是值类型.这可能不是您正在寻找的行为,这也是为什么没有其他信息我会考虑接下来的两个选项之一.

二是要增加一个约束条件BIComparable:

public class WidgetBox<A, B, C> where B : IComparable 
Run Code Online (Sandbox Code Playgroud)

以便

if(b.CompareTo(iteratorB) == 0) {
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

第三个是要求IEqualityComparer<B>传递给构造函数WidgetBox

public class WidgetBox<A, B, C> {
    IEqualityComparer<B> _comparer;
    public WidgetBox(IEqualityComparer<B> comparer) {
        _comparer = comparer;
    }
    // details elided
}
Run Code Online (Sandbox Code Playgroud)

然后:

if(_comparer.Equals(b, iteratorB)) {
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

使用最后一个选项,您可以提供默认为的重载EqualityComparer<T>.Default:

public WidgetBox() : this(EqualityComparer<T>.Default) { }
Run Code Online (Sandbox Code Playgroud)