比较字符串与非字符串时不区分大小写
我创建了一个 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(object) 中很好地发挥作用:
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
}
}
有没有办法获取字符串.Equal(object) 实际上将 IString 作为字符串处理吗?
I created a C# struct which can generically handle case insensitive string comparisons, transparently. So for example:
List<IString> list = new List<IString>();
list.Add("help");
Assert.IsTrue(list.Contains("Help"));
or
Dictionary<IString, string> dict = new Dictionary<IString, string>();
dict["Help"] = "thanks!";
Assert.AreEqual("thanks!", dict["hELP"]);
But the one thing I can't figure out (and maybe it's not possible), is how to get class string to play nicely in .Equals(object):
IString A1 = "A";
string A2 = "a";
Assert.AreEqual(A1, A2, "This passes");
Assert.AreEqual(A2, A1, "This fails");
Here's the code:
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
}
}
Is there any way to get string.Equal(object) to actually deal with IString as a string?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不需要首先创建这样的类型。
相反,您应该使用
StringComparer
类。例如:
或者
还请注意,不应将其命名为
IString
;只有接口应该以I
开头。回答你的问题,不;那是不可能的。
You don't need to create such a type in the first place.
Instead, you should use the
StringComparer
class.For example:
Or
Also note that it shouldn't be named
IString
; only interfaces should begin withI
.To answer your question, no; that's impossible.
不,没有。
String.Equals(object)
方法对所提供的String
类型值具有严格依赖性。它执行 CLR 类型检查,不考虑任何用户定义的转换或函数,因此仅适用于 System.String 的实例No there is not. The
String.Equals(object)
method has a hard dependency on the provided value being of the typeString
. It does a CLR type check which does not consider any user defined conversions or functions and hence will only work with an instance ofSystem.String