我喜欢重载解决方案,但它需要通过http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80).aspx完成
研究@Jeppe Stig Nielsen 表明这OrdinalIgnoreCase
最适合我的比较。
“使用 OrdinalIgnoreCase 进行的比较在行为上是两个调用的组合:在两个字符串参数上调用 ToUpperInvariant,并进行 Ordinal 比较。 ” [http://msdn.microsoft.com/en-us/library/ms973919.aspx]
基于这个引文,我return this.Key.ToUpperInvariant().GetHashCode();
在GetHashCode()
重载中选择了。
类实现
public class MyKeyValuePair
{
private readonly KeyValuePair<string, int> myKeyValuePair;
public MyKeyValuePair(string key, int value)
{
myKeyValuePair = new KeyValuePair<string, int>(key, value);
}
public string Key { get { return myKeyValuePair.Key; } }
public int Value { get { return myKeyValuePair.Value; } }
public static bool operator ==(MyKeyValuePair a, MyKeyValuePair b)
{
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
if (((object)a == null) || ((object)b == null))
{
return false;
}
return a.Key.Equals(b.Key, StringComparison.OrdinalIgnoreCase);
}
public static bool operator !=(MyKeyValuePair a, MyKeyValuePair b)
{
return !(a == b);
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
MyKeyValuePair p = obj as MyKeyValuePair;
if ((object)p == null)
{
return false;
}
return this.Key == p.Key;
}
public bool Equals(MyKeyValuePair obj)
{
if ((object)obj == null)
{
return false;
}
return this.Key.Equals(obj.Key, StringComparison.OrdinalIgnoreCase);
}
public override int GetHashCode()
{
return this.Key.ToUpperInvariant().GetHashCode();
}
}
测试方法
public void MyKeyValuePairCaseInsensitiveKeyComparisonWorksCorrectly()
{
var x = new MyKeyValuePair("testvalue", 5);
var y = new MyKeyValuePair("testvalue", 6);
var z = new MyKeyValuePair("testvalue", 7);
Assert.True(x == x, "== identity");
Assert.True((x == y) == (y == x), "equals commutative");
Assert.True(x == y, "== if x == y");
Assert.True(y == x, "== and y == z");
Assert.True(x == z, "== then x equals z");
for (var successive_invocations = 0; successive_invocations < 3; successive_invocations++)
{
Assert.True(x == y, "== successive invocations");
}
Assert.False(x == null);
Assert.True(x.Equals(x), "equals identity");
Assert.True(x.Equals(y) == y.Equals(x), "equals commutative");
Assert.True(x.Equals(y), "equals if x == y");
Assert.True(y.Equals(x), "equals and y == z");
Assert.True(x.Equals(z), "equals then x equals z");
for (var successive_invocations = 0; successive_invocations < 3; successive_invocations++)
{
Assert.True(x.Equals(y), "equals successive invocations");
}
Assert.False(x.Equals(null));
// show correct behavior
var capi = "I";
var lowi = "i";
var capti = "İ";
var lowti = "ı";
Assert.True(capi.Equals(lowi, StringComparison.OrdinalIgnoreCase), "capi == lowi");
Assert.False(capi.Equals(capti, StringComparison.OrdinalIgnoreCase), "capi != capti");
Assert.False(capi.Equals(lowti, StringComparison.OrdinalIgnoreCase), "capi != lowti");
Assert.False(lowi.Equals(capti, StringComparison.OrdinalIgnoreCase), "lowi != capti");
Assert.False(lowi.Equals(lowti, StringComparison.OrdinalIgnoreCase), "lowi != lowti");
Assert.False(capti.Equals(lowti, StringComparison.OrdinalIgnoreCase), "capti != lowti");
//test actual behavior
var a = new MyKeyValuePair(capi, 1);
var b = new MyKeyValuePair(lowi, 2);
var c = new MyKeyValuePair(capti, 3);
var d = new MyKeyValuePair(lowti, 4);
Assert.True(a.Equals(b), "a == b");
Assert.False(a.Equals(c), "a != c");
Assert.False(a.Equals(d), "a != d");
Assert.False(b.Equals(c), "b != c");
Assert.False(b.Equals(d), "b != d");
Assert.False(c.Equals(d), "c != d");
}