c# - 无法比较通用值

标签 c# .net 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.
        ...
    }
}

错误:运算符“==”不能应用于“V”和“V”类型的操作数

如果我不能比较类型,我该如何实现包含?字典、列表和所有其他通用容器是如何做到的??

最佳答案

这里有几个选项

首先是使用Object.Equals :

if(b.Equals(iteratorB)) {
    // do stuff
}

小心使用这个选项;如果B不会覆盖 Object.Equals那么当 B 时默认比较是引用相等B 时是引用类型和值相等是一个值类型。这可能不是您正在寻求的行为,这就是为什么在没有其他信息的情况下我会考虑接下来两个选项之一的原因。

第二个是添加一个约束 BIComparable :

public class WidgetBox<A, B, C> where B : IComparable 

这样

if(b.CompareTo(iteratorB) == 0) {
    // do stuff
}

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

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

然后:

if(_comparer.Equals(b, iteratorB)) {
    // do stuff
}

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

public WidgetBox() : this(EqualityComparer<T>.Default) { }

关于c# - 无法比较通用值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2238651/

相关文章:

c# - 兼容模式开启时如何判断正确的浏览器版本

c++ - MISRA C++ 规则 14-5-1:(不要在关联的命名空间中声明泛型函数)是否适用于 std::operator<<?

C# - 为什么我不能创建通用接口(interface)类型的 IEnumerable?

c# - 无法使用集合初始值设定项初始化类型 '',因为它未实现 'System.Collections.IEnumerable'

c# - 如何从二进制数组作为资源在 C# 中将程序集加载并执行到内存中

c# - 有什么理由更喜欢单精度而不是 double 据类型?

c# - C# 中的函数 - 如何将整数值放入函数中?

c# - 在非静态类中,如何保留在多个不同类中同时调用的静态方法中使用的静态变量的值

.net - F# JSON 类型提供程序 : Handling DateTime and TimeZone

java - 通用的测试方法参数