我最初的假设是,因为它是泛型的,所以它不能像对字符串所做的那样在幕后引用值转换。我想整理一个支持这一点的例子。:) 我不得不做出一些假设来为此组合一些东西,所以我的例子可能不是 100% 的。(我使用的代码在底部)
当我刚刚编译时,我无法编译任何东西
class Comparer<T, TId>
{
private readonly Func<T, TId> m_idfunc;
public Comparer(Func<T, TId> idFunc)
{
m_idfunc = idFunc;
}
public bool Equals(T x, T y)
{
var xid = m_idfunc(x);
var yid = m_idfunc(y);
return (TId)xid == (TId)yid;
}
}
我找到了https://stackoverflow.com/a/390919/156708并将类声明修改为
class Comparer<T, TId> where TId : class
并编译。步骤1。
我将Equals
功能设置为
public bool Equals(T x, T y)
{
var xid = m_idfunc(x);
var yid = m_idfunc(y);
return (TId)xid == (TId)yid;
}
结果是False
(请参阅在 xid|yid 中生成值的完整代码)。符合我的假设,即泛型对此有所帮助。还不够,需要看看如果删除了泛型方面会发生什么。
Comparer
将班级更改为
class Comparer<T>
{
private readonly Func<T, string> m_idfunc;
public Comparer(Func<T, string> idFunc)
{
m_idfunc = idFunc;
}
public bool Equals(T x, T y)
{
var xid = m_idfunc(x);
var yid = m_idfunc(y);
return xid == yid;
}
}
返回True
。
我对此不是 100% 的,但我的假设是基于类的==
操作员进行string
值检查而不是参考检查的事实。使用泛型时,很可能设置为仅进行引用检查(尚未深入到 IL 中查看它在那里做了什么),如果内存中的字符串位置不同,那么它将返回 false。(我有点想知道细节,因为我不知道它们,只是一个似乎有效的工作假设)
我使用泛型的完整示例代码如下。
using System;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
var compare = new Comparer<Example, string>(example => example.id(example));
var ex1 = new Example();
var ex2 = new Example();
Console.WriteLine(compare.Equals(ex1, ex2));
Console.ReadLine();
}
class Example
{
public string id(Example example)
{
return new string(new [] {'f', 'o', 'o'});
}
}
class Comparer<T, TId> where TId : class
{
private readonly Func<T, TId> m_idfunc;
public Comparer(Func<T, TId> idFunc)
{
m_idfunc = idFunc;
}
public bool Equals(T x, T y)
{
var xid = m_idfunc(x);
var yid = m_idfunc(y);
return (TId)xid == (TId)yid;
}
}
}
}
希望这会有所帮助……而且我的推理并没有大错特错。:)