C# 更改方法,使其搜索区分大小写

C# 更改方法,使其搜索区分大小写,c#,csv,dictionary,string-comparison,keyvaluepair,C#,Csv,Dictionary,String Comparison,Keyvaluepair,我有两个方法需要修复,这样当用户搜索“Javascript”时,如果这些方法拼写为“Javascript”或“Javascript”,它们将返回值——大写无关紧要。已使用LoadData()从csv文件(方法在其中执行搜索)导入数据。可以找到我正在使用的三个文件(JobData.cs、Program.cs、job_data.csv)的完整代码 我需要修复的第一个方法是这个(: 我尝试使用不区分大小写的字符串比较。但使用该行会显示错误消息: The name "culture" does not

我有两个方法需要修复,这样当用户搜索“Javascript”时,如果这些方法拼写为“Javascript”或“Javascript”,它们将返回值——大写无关紧要。已使用
LoadData()
从csv文件(方法在其中执行搜索)导入数据。可以找到我正在使用的三个文件(JobData.cs、Program.cs、job_data.csv)的完整代码

我需要修复的第一个方法是这个(:

我尝试使用不区分大小写的字符串比较。但使用该行会显示错误消息:

The name "culture" does not exist in the current context
The name "CompareOptions" does not exist in the current context

关于如何将
searchTerms
field.aValue
进行比较时不区分大小写,还有什么其他想法吗?

首先,我们要说的是,不能比较字符串,也不能区分大小写。它们始终是因为大小写字母具有不同的Unicode值。下面是您的解决方案:

如果要全面检查每个字符串,可以使用
ToUpper()
ToLower()
方法。例如:

string s1 = "JavaScript";
string s2 = "Javascript";

if (s1.ToLower() == s2.ToLower())
{
    //Do something
}
它同样适用于
ToUpper()
,因为:

//s1.ToLower() == "javascript";
//s1.ToUpper() == "JAVASCRIPT";
因此,根据您的情况,假设您的
字典
中填充了所有小写字符串,您可以简单地说:

if (aValue.Contains(searchTerm.ToLower()))
{
    //Do something
}
有关这些函数的更多信息,请查看



多年来,我一直在研究这个问题,我能想到的最健壮的解决方案是创建一个类似于
字符串的包装器,它以不区分大小写的方式完成所有工作。尽管这取决于您的需要,但可能有些过火

用途是:

using StringOrdinalIgnoreCase = JDanielSmith.System.String<JDanielSmith.System.OrdinalIgnoreCase>;

[TestMethod]
public void StringOrdinalIgnoreCaseDictionary()
{
    var d = new Dictionary<StringOrdinalIgnoreCase, int>() { { "abc", 1 }, { "def", 2 } };
    Assert.IsTrue(d.ContainsKey("ABC"));

    try
    {
        d.Add("DEF", 2);
        Assert.Fail();
    }
    catch (ArgumentException) { }
}
使用StringOrdinalIgnoreCase=JDanielSmith.System.String;
[测试方法]
public void StringOrdinalIgnoreCaseDictionary()
{
var d=newdictionary(){{“abc”,1},{“def”,2};
资产净值(d.ContainsKey(“ABC”));
尝试
{
d、 添加(“定义”,2);
Assert.Fail();
}
捕获(参数异常){}
}
String.cs
使用系统;
使用CodeAnalysis=System.Diagnostics.CodeAnalysis;
名称空间MyNS.System
{
/// 
///在System.String周围提供不区分大小写的包装。
/// 
///这在集合中使用字符串作为键时特别有用,其中键类似于Windows文件系统路径名;
///很容易忘记在构造函数中传递IEqualityComparer。
/// 
///以下是一些提示:http://stackoverflow.com/questions/33039324/how-can-system-string-be-properly-wrapped-for-case-insensitivy
/// 
[CodeAnalysis.SuppressMessage(“Microsoft.Naming”,“CA1716:IdentifiersShouldNotMatchKeywords”,MessageId=“String”)]
[CodeAnalysis.SuppressMessage(“Microsoft.Design”,“CA1036:OverrideMethodsOnComparableTypes”)]
公共密封类字符串:IComparable、iClonable、,
我可比,我可比,
可比
其中TComparerAndComparison:StringComparerAndComparison,new()
{
静态只读StringComparerAndComparison _comparerAndComparison=新的TComparerAndComparison();
静态只读StringComparer\u comparer=\u comparerAndComparison.comparer;
静态只读StringComparison\u comparisonType=\u comparerAndComparison.Comparison;
公共字符串值{get;}
公共字符串(字符串值)
{
//如果“Value”从不为null,则匹配System.String的行为更直接
值=值??字符串。为空;
}
//轻松转换为System.String或从System.String转换为System.String
公共静态隐式运算符字符串(字符串源)=>新字符串(源);
公共静态隐式运算符字符串(字符串源)=>source?.Value;
#区域相等,相等
公共覆盖布尔等于(对象对象对象)
{
if(Object.ReferenceEquals(obj,null))
返回false;//此!=null
var other=obj作为字符串;
如果(!Object.ReferenceEquals(其他,空))
返回等于(其他);//调用等于(字符串)
var s_other=obj作为字符串;
如果(!Object.ReferenceEquals(s_other,null))
return Equals(s_other);//call Equals(string)
返回比较器等于(obj);
}
公共布尔等于(字符串其他)
{
if(Object.ReferenceEquals(other,null))
返回false;//此!=null
return Equals(other.Value);//call Equals(string)
}
public bool Equals(字符串其他)=>\u comparer.Equals(值,其他);
公共覆盖int GetHashCode()
{
返回\u comparer.GetHashCode(值);
}
#端区
公共重写字符串ToString()=>值;
公共对象克隆()=>新字符串(值);
#区域不可比
公共整数比较(对象对象对象)
{
// https://msdn.microsoft.com/en-us/library/4d7sx9hd(v=vs.110).aspx
if(Object.ReferenceEquals(obj,null))
返回1;//如果other不是有效的对象引用,则此实例更大。
//obj必须是StringOrdinalIgnoreCase或String
var other=obj作为字符串;
if(Object.ReferenceEquals(other,null))
{
var s_other=obj作为字符串;
if(Object.ReferenceEquals(s_other,null))
抛出新ArgumentException(“对象的类型必须为“+nameof(String)+”或String.”);
返回CompareTo(s_other);//调用CompareTo(string)
}
返回CompareTo(其他);//调用CompareTo(StringOrdinalIgnoreCase)
}
公共整数比较(字符串其他)
{
// https://msdn.microsoft.com/en-us/library/4d7sx9hd(v=vs.110).aspx
if(Object.ReferenceEquals(other,null))
if (aValue.Contains(searchTerm.ToLower()))
{
    //Do something
}
using StringOrdinalIgnoreCase = JDanielSmith.System.String<JDanielSmith.System.OrdinalIgnoreCase>;

[TestMethod]
public void StringOrdinalIgnoreCaseDictionary()
{
    var d = new Dictionary<StringOrdinalIgnoreCase, int>() { { "abc", 1 }, { "def", 2 } };
    Assert.IsTrue(d.ContainsKey("ABC"));

    try
    {
        d.Add("DEF", 2);
        Assert.Fail();
    }
    catch (ArgumentException) { }
}
using System;

using CodeAnalysis = System.Diagnostics.CodeAnalysis;

namespace MyNS.System
{
    /// <summary>
    /// Provide a case-insensitive wrapper around System.String.
    /// 
    /// This is especially useful when using strings as keys in collections, where the key is something like a Windows file-system pathname;
    /// it can be easy to forget to pass an IEqualityComparer<> in the constructor.
    /// 
    /// Some hints from: http://stackoverflow.com/questions/33039324/how-can-system-string-be-properly-wrapped-for-case-insensitivy
    /// </summary>
    [CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "String")]
    [CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1036:OverrideMethodsOnComparableTypes")]
    public sealed class String<TComparerAndComparison> : IComparable, ICloneable,
        IComparable<String<TComparerAndComparison>>, IEquatable<String<TComparerAndComparison>>,
        IComparable<String>, IEquatable<String>
        where TComparerAndComparison : StringComparerAndComparison, new()
    {
        static readonly StringComparerAndComparison _comparerAndComparison = new TComparerAndComparison();
        static readonly StringComparer _comparer = _comparerAndComparison.Comparer;
        static readonly StringComparison _comparisonType = _comparerAndComparison.Comparison;

        public string Value { get; }

        public String(string value)
        {
            // matching the behavior of System.String is more straight-forward if "Value" is never null
            Value = value ?? String.Empty;
        }

        // easily convert to/from System.String
        public static implicit operator String<TComparerAndComparison>(string source) => new String<TComparerAndComparison>(source);
        public static implicit operator string(String<TComparerAndComparison> source) => source?.Value;

        #region Equals, IEquatable
        public override bool Equals(object obj)
        {
            if (Object.ReferenceEquals(obj, null))
                return false; // this != null

            var other = obj as String<TComparerAndComparison>;
            if (!Object.ReferenceEquals(other, null))
                return Equals(other); // call Equals(String<TStringComparerAndComparison>)

            var s_other = obj as string;
            if (!Object.ReferenceEquals(s_other, null))
                return Equals(s_other); // call Equals(string)

            return _comparer.Equals(obj);
        }
        public bool Equals(String<TComparerAndComparison> other)
        {
            if (Object.ReferenceEquals(other, null))
                return false; // this != null
            return Equals(other.Value); // call Equals(string)
        }
        public bool Equals(string other) => _comparer.Equals(Value, other);

        public override int GetHashCode()
        {
            return _comparer.GetHashCode(Value);
        }
        #endregion

        public override string ToString() => Value;

        public object Clone() => new String<TComparerAndComparison>(Value);

        #region IComparable
        public int CompareTo(object obj)
        {
            // https://msdn.microsoft.com/en-us/library/4d7sx9hd(v=vs.110).aspx
            if (Object.ReferenceEquals(obj, null))
                return 1; // If other is not a valid object reference, this instance is greater.

            // obj must be either StringOrdinalIgnoreCase or String
            var other = obj as String<TComparerAndComparison>;
            if (Object.ReferenceEquals(other, null))
            {
                var s_other = obj as string;
                if (Object.ReferenceEquals(s_other, null))
                    throw new ArgumentException("Object must be of type " + nameof(String<TComparerAndComparison>) + " or String.");

                return CompareTo(s_other); // call CompareTo(string)
            }

            return CompareTo(other); // call CompareTo(StringOrdinalIgnoreCase)
        }
        public int CompareTo(String<TComparerAndComparison> other)
        {
            // https://msdn.microsoft.com/en-us/library/4d7sx9hd(v=vs.110).aspx
            if (Object.ReferenceEquals(other, null))
                return 1; // If other is not a valid object reference, this instance is greater.

            if (Object.ReferenceEquals(Value, other.Value))
                return 0;

            return CompareTo(other.Value); // call CompareTo(string)
        }
        public int CompareTo(string other)
        {
            // https://msdn.microsoft.com/en-us/library/4d7sx9hd(v=vs.110).aspx
            if (Object.ReferenceEquals(other, null))
                return 1; // If other is not a valid object reference, this instance is greater.

            return _comparer.Compare(Value, other);
        }

        public static bool operator ==(String<TComparerAndComparison> x, String<TComparerAndComparison> y)
        {
            if (Object.ReferenceEquals(x, null))
                return Object.ReferenceEquals(y, null); // null == null, null != something
            return x.Equals(y); // know x != null
        }
        public static bool operator ==(String<TComparerAndComparison> x, string y)
        {
            if (Object.ReferenceEquals(x, null))
                return Object.ReferenceEquals(y, null); // null == null, null != something
            return x.Equals(y); // know x != null
        }
        public static bool operator ==(string x, String<TComparerAndComparison> y) => y == x; // == is commutative, x == y
        public static bool operator !=(String<TComparerAndComparison> x, String<TComparerAndComparison> y) => !(x == y);
        public static bool operator !=(string x, String<TComparerAndComparison> y) => !(x == y);
        public static bool operator !=(String<TComparerAndComparison> x, string y) => !(x == y);
        #endregion

        #region IndexOf, LastIndexOf, StartsWith, EndsWith
        public bool EndsWith(string value) => Value.EndsWith(value, _comparisonType);
        public int IndexOf(string value) => Value.IndexOf(value, _comparisonType);
        public int IndexOf(string value, int startIndex) => Value.IndexOf(value, startIndex, _comparisonType);
        public int IndexOf(string value, int startIndex, int count) => Value.IndexOf(value, startIndex, count, _comparisonType);
        public int LastIndexOf(string value) => Value.LastIndexOf(value, _comparisonType);
        public int LastIndexOf(string value, int startIndex) => Value.LastIndexOf(value, startIndex, _comparisonType);
        public int LastIndexOf(string value, int startIndex, int count) => Value.LastIndexOf(value, startIndex, count, _comparisonType);
        public bool StartsWith(string value) => Value.StartsWith(value, _comparisonType);
        #endregion

    }
}
using System;

using StringComparer = System.StringComparer;
using StringComparison = System.StringComparison;

namespace JDanielSmith.System
{
    /// <summary>
    /// Pass around System.StringComparer and System.StringComparison together.
    /// Also, provides a base class for generics.
    /// </summary>
    public abstract class StringComparerAndComparison
    {
        internal StringComparer Comparer { get; }
        internal StringComparison Comparison { get; }
        internal StringComparerAndComparison(StringComparer comparer, StringComparison comparison)
        {
            if (comparer == null) throw new ArgumentNullException(nameof(comparer));

            Comparer = comparer;
            Comparison = comparison;
        }
    }

    public sealed class CurrentCulture : StringComparerAndComparison
    {
        public CurrentCulture() : base(StringComparer.CurrentCulture, StringComparison.CurrentCulture) { }
    }

    public sealed class CurrentCultureIgnoreCase : StringComparerAndComparison
    {
        public CurrentCultureIgnoreCase() : base(StringComparer.CurrentCultureIgnoreCase, StringComparison.CurrentCultureIgnoreCase) { }
    }

    public sealed class InvariantCulture : StringComparerAndComparison
    {
        public InvariantCulture() : base(StringComparer.InvariantCulture, StringComparison.InvariantCulture) { }
    }

    public sealed class InvariantCultureIgnoreCase : StringComparerAndComparison
    {
        public InvariantCultureIgnoreCase() : base(StringComparer.InvariantCultureIgnoreCase, StringComparison.InvariantCultureIgnoreCase) { }
    }

    public sealed class Ordinal : StringComparerAndComparison
    {
        public Ordinal() : base(StringComparer.Ordinal, StringComparison.Ordinal) { }
    }

    public sealed class OrdinalIgnoreCase : StringComparerAndComparison
    {
        public OrdinalIgnoreCase() : base(StringComparer.OrdinalIgnoreCase, StringComparison.OrdinalIgnoreCase) { }
    }
}
aValue.Contains(searchTerm)
aValue.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0