C# 不区分大小写比较字符串与非字符串

C# 不区分大小写比较字符串与非字符串,c#,string,equals,case-insensitive,C#,String,Equals,Case Insensitive,我创建了一个C#结构,它可以透明地处理不区分大小写的字符串比较。例如: List<IString> list = new List<IString>(); list.Add("help"); Assert.IsTrue(list.Contains("Help")); var dict = new Dictionary<String, string>(StringComparer.OrdinalIgnoreCase); dict["Help"] = "than

我创建了一个C#结构,它可以透明地处理不区分大小写的字符串比较。例如:

List<IString> list = new List<IString>();
list.Add("help");
Assert.IsTrue(list.Contains("Help"));
var dict = new Dictionary<String, string>(StringComparer.OrdinalIgnoreCase);
dict["Help"] = "thanks!";
Assert.AreEqual("thanks!", dict["hELP"]);
代码如下:

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

    }
}
使用系统;
使用System.Collections.Generic;
命名空间Util
{
/// 
///string类的不区分大小写的包装器
/// 
公共结构IString:
我比较,
我可比,
我可比,
我可比,
合理的,
充足的
{
private const StringComparison icase=StringComparison.OrdinalIgnoreCase;
公共只读字符串值;
公共IString(字符串值)
{
这个。值=值;
}
公共布尔等于(字符串其他)
{
返回字符串.Equals(值、其他、icase);
}
公共布尔等于(IString Other)
{
返回字符串.Equals(Value,Other.Value,icase);
}
公共覆盖布尔等于(对象对象对象)
{
if(obj是字符串| | obj是字符串)
{
返回字符串.Equals(Value,obj.ToString(),icase);
}
其他的
{
返回false;
}
}
public int IndexOf(字符串其他)
{
返回Other.IndexOf(Other,icase);
}
公共布尔包含(字符串其他)
{
返回指数(其他)>=0;
}
公共覆盖int GetHashCode()
{
如果(值==null)
返回0;
其他的
返回StringComparer.OrdinalIgnoreCase.GetHashCode(值);
}
公共重写字符串ToString()
{
返回值;
}
公共整数比较(IString x,IString y)
{
返回字符串.Compare(x.Value,y.Value,icase);
}
公共整数比较(字符串x、字符串y)
{
返回字符串.Compare(x,y,icase);
}
公共整数比较(对象对象对象)
{
如果(obj正在启动)
返回比较(本(IString)obj);
else if(obj是字符串)
返回比较(值,(字符串)对象);
else if(值!=null)
返回值。比较对象(obj);
其他的
返回-1;
}
公共int比较(IString其他)
{
返回比较(此,其他);
}
公共整数比较(字符串其他)
{
返回比较(值、其他);
}
公共静态隐式运算符字符串(IString From)
{
从.Value返回;
}
公共静态隐式运算符IString(字符串来自)
{
返回新的IString(从);
}
#区域IString到IString运算符
公共静态布尔运算符==(IString Str1,IString Str2)
{
返回字符串.Equals(Str1.Value、Str2.Value、icase);
}
公共静态布尔运算符!=(IString Str1,IString Str2)
{
return!string.Equals(Str1.Value、Str2.Value、icase);
}
公共静态IString运算符+(IString Str1、IString Str2)
{
返回(IString)(Str1.Value+Str2.Value);
}
公共静态布尔运算符>(IString Str1、IString Str2)
{
返回Str1.CompareTo(Str2)>0;
}
公共静态布尔运算符>=(IString Str1,IString Str2)
{
返回Str1.CompareTo(Str2)>=0;
}
公共静态布尔运算符0;
}
公共静态布尔运算符>=(IString Str1,string Str2)
{
返回Str1.CompareTo(Str2)>=0;
}

公共静态布尔运算符您首先不需要创建这样的类型。
相反,您应该使用
StringComparer

例如:

List<IString> list = new List<IString>();
list.Add("help");
Assert.IsTrue(list.Contains("Help"));
var dict = new Dictionary<String, string>(StringComparer.OrdinalIgnoreCase);
dict["Help"] = "thanks!";
Assert.AreEqual("thanks!", dict["hELP"]);
var dict=新字典(StringComparer.OrdinalIgnoreCase);
dict[“Help”]=“谢谢!”;
Assert.AreEqual(“谢谢!”,dict[“帮助]);

List List=新列表();
列表。添加(“帮助”);
IsTrue(list.Contains(“Help”,StringComparer.OrdinalIgnoreCase));
还请注意,它不应命名为
IString
;只有接口应以
I
开头


回答你的问题,不,那是不可能的。

不,没有。
字符串.Equals(object)< /代码>方法对类型<代码>字符串< /代码>所提供的值有很强的依赖性。它执行CLR类型检查,它不考虑任何用户定义的转换或函数,因此只适用于<代码> Stry.String < /Calp> < /P>的实例。您应该使用<代码> OrdinalIgnoreCase < /代码>而不是<代码>eCase
;它更快、更安全。此外,
返回StringComparer.OrdinalIgnoreCase.GetHashCode(值)
。除此之外,还有一个事实,那就是首先不需要它,您的结构看起来相当不错。@SLaks:好的,我将切换到序号。@CodeInChaos:是的,我同意IString看起来像一个接口。但是想要它的部分原因是为了简洁,以避免一堆“StringComparison.OrdinalingOreCase”把所有的东西都塞满,让代码更易读。所以如果有人建议用一个更好的名字,我当然很感兴趣。@Bryce:InsensitiveEstring
CaselessString
UncasedString
怎么样?
List<String> list = new List<String>();
list.Add("help");
Assert.IsTrue(list.Contains("Help", StringComparer.OrdinalIgnoreCase));