我創建了一個C#結構,它可以一般性地處理不區分大小寫的字符串比較。因此,例如:不區分大小寫的比較字符串與非字符串
List<IString> list = new List<IString>();
list.Add("help");
Assert.IsTrue(list.Contains("Help"));
或
Dictionary<IString, string> dict = new Dictionary<IString, string>();
dict["Help"] = "thanks!";
Assert.AreEqual("thanks!", dict["hELP"]);
但有一件事我想不出(也許這是不可能的),是如何得到的類別字符串在.Equals發揮很好(對象):
IString A1 = "A";
string A2 = "a";
Assert.AreEqual(A1, A2, "This passes");
Assert.AreEqual(A2, A1, "This fails");
下面的代碼:
using System;
using System.Collections.Generic;
namespace Util
{
/// <summary>
/// Case insensitive wrapper for the string class
/// </summary>
public struct IString :
IComparer<IString>,
IComparable,
IComparable<IString>,
IComparable<string>,
IEquatable<string>,
IEquatable<IString>
{
private const StringComparison icase = StringComparison.OrdinalIgnoreCase;
public readonly string Value;
public IString(string Value)
{
this.Value = Value;
}
public bool Equals(string Other)
{
return string.Equals(Value, Other, icase);
}
public bool Equals(IString Other)
{
return string.Equals(Value, Other.Value, icase);
}
public override bool Equals(object obj)
{
if (obj is IString || obj is string)
{
return string.Equals(Value, obj.ToString(), icase);
}
else
{
return false;
}
}
public int IndexOf(string Other)
{
return Other.IndexOf(Other, icase);
}
public bool Contains(string Other)
{
return IndexOf(Other) >= 0;
}
public override int GetHashCode()
{
if (Value == null)
return 0;
else
return StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
}
public override string ToString()
{
return Value;
}
public int Compare(IString x, IString y)
{
return string.Compare(x.Value, y.Value, icase);
}
public int Compare(string x, string y)
{
return string.Compare(x, y, icase);
}
public int CompareTo(object obj)
{
if (obj is IString)
return Compare(this, (IString)obj);
else if (obj is string)
return Compare(Value, (string)obj);
else if (Value != null)
return Value.CompareTo(obj);
else
return -1;
}
public int CompareTo(IString other)
{
return Compare(this, other);
}
public int CompareTo(string other)
{
return Compare(Value, other);
}
public static implicit operator string(IString From)
{
return From.Value;
}
public static implicit operator IString(string From)
{
return new IString(From);
}
#region IString to IString operators
public static bool operator ==(IString Str1, IString Str2)
{
return string.Equals(Str1.Value, Str2.Value, icase);
}
public static bool operator !=(IString Str1, IString Str2)
{
return !string.Equals(Str1.Value, Str2.Value, icase);
}
public static IString operator +(IString Str1, IString Str2)
{
return (IString)(Str1.Value + Str2.Value);
}
public static bool operator >(IString Str1, IString Str2)
{
return Str1.CompareTo(Str2) > 0;
}
public static bool operator >=(IString Str1, IString Str2)
{
return Str1.CompareTo(Str2) >= 0;
}
public static bool operator <(IString Str1, IString Str2)
{
return Str1.CompareTo(Str2) < 0;
}
public static bool operator <=(IString Str1, IString Str2)
{
return Str1.CompareTo(Str2) <= 0;
}
#endregion IString to IString operators
#region string to IString operators
public static bool operator ==(string Str1, IString Str2)
{
return string.Equals(Str1, Str2.Value, icase);
}
public static bool operator !=(string Str1, IString Str2)
{
return !string.Equals(Str1, Str2.Value, icase);
}
public static IString operator +(string Str1, IString Str2)
{
return (IString)(Str1 + Str2.Value);
}
public static bool operator >(string Str1, IString Str2)
{
return Str2.CompareTo(Str1) < 0;
}
public static bool operator >=(string Str1, IString Str2)
{
return Str2.CompareTo(Str1) <= 0;
}
public static bool operator <(string Str1, IString Str2)
{
return Str2.CompareTo(Str1) > 0;
}
public static bool operator <=(string Str1, IString Str2)
{
return Str2.CompareTo(Str1) >= 0;
}
#endregion string to IString operators
#region IString to string operators
public static bool operator ==(IString Str1, string Str2)
{
return string.Equals(Str1.Value, Str2, icase);
}
public static bool operator !=(IString Str1, string Str2)
{
return !string.Equals(Str1.Value, Str2, icase);
}
public static IString operator +(IString Str1, string Str2)
{
return (IString)(Str1.Value + Str2);
}
public static bool operator >(IString Str1, string Str2)
{
return Str1.CompareTo(Str2) > 0;
}
public static bool operator >=(IString Str1, string Str2)
{
return Str1.CompareTo(Str2) >= 0;
}
public static bool operator <(IString Str1, string Str2)
{
return Str1.CompareTo(Str2) < 0;
}
public static bool operator <=(IString Str1, string Str2)
{
return Str1.CompareTo(Str2) <= 0;
}
#endregion IString to string operators
}
}
有沒有什麼辦法讓string.Equal(object)實際處理IString作爲一個字符串?
您應該使用'OrdinalIgnoreCase'而不是'InvariantCultureIgnoreCase';它更快,更安全。 – SLaks 2010-11-17 17:09:00
另外,'返回StringComparer.OrdinalIgnoreCase.GetHashCode(Value);'。 – SLaks 2010-11-17 17:09:19
除此之外,事實上它不是必需的,你的結構看起來不錯。 – SLaks 2010-11-17 17:10:03