相关疑难解决方法(0)

运算符==不能应用于C#中的泛型类型吗?

根据MSDN中==运营商的文档,

对于预定义的值类型,如果操作数的值相等,则相等运算符(==)返回true,否则返回false.对于除string之外的引用类型,如果其两个操作数引用同一对象,则==返回true.对于字符串类型,==比较字符串的值.用户定义的值类型可以重载==运算符(请参阅运算符).用户定义的引用类型也是如此,尽管 默认情况下==的行为与上述预定义和用户定义的引用类型相同.

那么为什么这段代码片段无法编译呢?

bool Compare<T>(T x, T y) { return x == y; }
Run Code Online (Sandbox Code Playgroud)

我得到错误运算符'=='不能应用于'T'和'T'类型的操作数.我想知道为什么,因为据我所知,==运算符是针对所有类型预定义的?

编辑:谢谢大家.起初我没有注意到该声明仅涉及引用类型.我还认为为所有值类型提供了逐位比较,我现在知道这是正确的.

但是,如果我使用引用类型,==操作符是否会使用预定义的引用比较,或者如果类型定义了一个,它是否会使用运算符的重载版本?

编辑2:通过反复试验,我们了解到==操作员在使用不受限制的泛型类型时将使用预定义的参考比较.实际上,编译器将使用它可以为限制类型参数找到的最佳方法,但不会再看了.例如,true即使Test.test<B>(new B(), new B())被调用,下面的代码也会始终打印:

class A { public static bool operator==(A x, A y) { return true; } }
class B : A { public static bool operator==(B x, B y) { return false; } }
class Test { void test<T>(T a, T …
Run Code Online (Sandbox Code Playgroud)

c# generics operators equals-operator

309
推荐指数
10
解决办法
10万
查看次数

在IEqualityComparer中包装委托

几个Linq.Enumerable函数需要一个IEqualityComparer<T>.是否有一个方便的包装类适应delegate(T,T)=>bool实现IEqualityComparer<T>?编写一个很容易(如果你忽略了定义正确的哈希码的问题),但我想知道是否有开箱即用的解决方案.

具体来说,我想对Dictionarys 进行集合操作,仅使用Keys来定义成员资格(同时根据不同的规则保留值).

.net linq delegates

125
推荐指数
7
解决办法
4万
查看次数

运算符'=='无法应用于类型T?

我认为这种方法有效,但我错了:

static void Equals<T>(T x, T y)
{
    return x == y;    //operator == can't be applied to type T
}
Run Code Online (Sandbox Code Playgroud)

在阅读了规范(v3.0中的第7.2.4节和v4.0中的第7.3.4节)之后:

7.2.4二元运算符重载决策

形式为x op y的操作,其中op是可重载的二元运算符,x是类型X的表达式,y是类型Y的表达式,按如下方式处理:

  • 由X和Y为操作运算符op(x,y)提供的候选用户定义运算符集合被确定.该集合由X提供的候选运算符和Y提供的候选运算符组合而成,每个运算符使用§7.2.5的规则确定.如果X和Y是相同类型,或者如果X和Y是从公共基类型派生的,则共享候选运算符仅出现在组合集中一次.

  • 如果候选用户定义的运算符集合不为空,则这将成为该操作的候选运算符集.否则,预定义的二元运算符op实现(包括它们的提升形式)将成为该操作的候选运算符集.给定运算符的预定义实现在运算符的描述中指定(第7.7节到第7.11节).

  • §7.4.3的重载决策规则应用于候选运算符集合,以根据参数列表(x,y)选择最佳运算符,并且此运算符成为重载解析过程的结果.如果重载解析无法选择单个最佳运算符,则会发生编译时错误.

在第2步中,我认为应该应用此预定义实现:

bool operator ==(object x, object y);
bool operator !=(object x, object y);
Run Code Online (Sandbox Code Playgroud)

因为C#中的所有内容都来自Object.如何在步骤3中发生编译时错误?在这种情况下,我不认为"重载决议无法选择".

编辑当我实现这样的事情时,我想到了这个问题:

class EnumComparer<TEnum> : IEqualityComparer<TEnum>
{
    public bool Equals(TEnum x, TEnum y)
    {
        return x == y;
    }
    public int GetHashCode(TEnum obj)
    {
        return (int)obj;
    }
}
Run Code Online (Sandbox Code Playgroud)

我担心我需要构建一个表达式并在Equals方法中动态调用它.

.net c# operator-overloading language-specifications

12
推荐指数
2
解决办法
2564
查看次数

将'=='运算符应用于泛型参数

可能重复:
不能将运算符==应用于C#中的泛型类型?

我有一个DatabaseLookup {}类,其中参数T将由类中的查找方法使用.在查找之前,我想知道是否已经查找过T之类的东西

if (T == previousLookupObject) ...
Run Code Online (Sandbox Code Playgroud)

这根本不编译.什么阻止我做这样的简单比较?

.net c# generics

7
推荐指数
2
解决办法
592
查看次数

比较两个值是否相等的最高效的方法是什么?

假设我在C#中有一个接受两个T类型值的泛型方法:

public void M<T>(T a, T b)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

在M()的内部体系中,我希望比较两个输入值是否相等.由于我对它们的运行时类型一无所知,除了它们是相同的类型,我可以使用object.Equals()静态方法做到这一点,并让它选择最佳方式:

public void M<T>(T a, T b)
{
    if (object.Equals(a, b))
    {
        ...
    }
    else
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

当T不是引用类型时,我在这里看到的问题是不必要的两个值的装箱.我想避免这种惩罚,因为M()被频繁调用.

我的问题是:有没有更好的方法来解决这个问题?我显然对一个解决方案感兴趣,这个解决方案不会过多地分析前面的T,这将抵消拳击规避的收益.

TIA.

.net c# generics boxing

2
推荐指数
1
解决办法
179
查看次数

如何比较泛型方法中的两个值?

我需要创建泛型方法,返回两个参数中的更多.运营商>和<不起作用.这是我方法的签名:

public static T Greater<T>(ref T a, ref T b)
{
    if (a > b) 
    {
       return a;
    }
    else 
    {
       return b;
    }
}
Run Code Online (Sandbox Code Playgroud)

我是C#中的新手,也是泛型类型的新手.

c# generics comparison

1
推荐指数
1
解决办法
227
查看次数