String比较null和empty相等的位置

时间:2009-11-25 14:54:48

标签: c#

使用C#和.NET 3.5,处理这种情况的最佳方法是什么。我有数百个字段可以从各种来源(主要是字符串)进行比较。有时,源将字符串字段返回为null,有时为空。当然,有时字段中会有文字。我当前对strA!= strB的比较并没有削减它,因为例如strA为null且strB为“”。我知道我可以做string.IsNullOrEmpty导致双重比较和一些丑陋。有没有更好的方法来处理这个?我认为扩展方法,但你不能扩展运算符。

我想我正在寻找一种性感的方式来做到这一点。

9 个答案:

答案 0 :(得分:62)

不会消除额外的潜在比较,但对于性感因素,您可以使用以下内容:

(strA ?? "") == (strB ?? "")

或稍微不那么性感,但更可取的形式:

(strA ?? string.Empty) == (strB ?? string.Empty)

答案 1 :(得分:58)

由于您需要进行数百次比较,因此您可能希望调用单个函数,以便减少代码中的混乱和重复。我不认为有一个内置函数可以在一个中进行空/空字符串/比较检查,但你可以自己创建一个:

static class Comparison
{
    public static bool AreEqual(string a, string b)
    {
        if (string.IsNullOrEmpty(a))
        {
            return string.IsNullOrEmpty(b);
        }
        else
        {
            return string.Equals(a, b);
        }
    }
}

然后你可以对每个比较使用一个函数调用:

        if(Comparison.AreEqual(strA[0], strB[0])) { // ... }
        if(Comparison.AreEqual(strA[1], strB[1])) { // ... }
        if(Comparison.AreEqual(strA[2], strB[2])) { // ... }
        if(Comparison.AreEqual(strA[3], strB[3])) { // ... }

如果您以后发现需要担心其他情况,例如忽略字符串开头或结尾处的空格,这种方法也更容易扩展;然后,您可以在函数中添加更多逻辑来进行修剪或其他任何操作,并且您不必对调用函数的数百行代码进行任何修改。

答案 2 :(得分:9)

不像??那样性感,但如果你将它短路,你可以避免双倍比较的部分:

string.IsNullOrEmpty( strA ) ? string.IsNullOrEmpty( strB ) : (strA == strB )

答案 3 :(得分:5)

怎么样?
strA ?? "" == strB ?? ""

答案 4 :(得分:2)

string.IsNullOrEmpty()有什么问题?我敢肯定,因为它是.NET框架的一部分,所以它已经过优化,可能比你或我可以写的东西效率更高。它可能不性感但它有效。编写易于阅读的代码,让编译器对细节进行整理。

答案 5 :(得分:1)

其他人给出的解决方案,包括建议为字符串定义比较类的解决方案,忘记为你的字符串写一个新的GetHashCode

这意味着您的字符串不能用于依赖于GetHashCode的{​​{1}}或Dictionary<T>的类。

请参阅 Why is it important to override GetHashCode when Equals method is overridden?

每当您决定为任何类更改 equality 的概念时,您应该为该类编写HashSet<T>。这可以确保如果根据您对对象的相等性的更改定义被认为是相等的,则它们的EqualityComparer将返回相等的值。

GetHashCode

用法:

public class NullStringComparer : EqualityComparer<string>
{
    public override bool Equals(string x, string y)
    {
        // equal if string.Equals(x, y)
        // or both StringIsNullOrEmpty
        return String.Equals(x, y)
            || (String.IsNullOrEmpty(x) && String.IsNullOrEmpty(y));
    }

    public override int GetHashCode(string obj)
    {
        if (String.IsNullOrEmpty(obj))
           return 0;
        else
            return obj.GetHashCode();
    }
}

答案 6 :(得分:0)

如果您的两组字段属于某种集合,则可以使用LINQ。如果它们是某种类型的集合,允许您通过键访问它们并且它们都具有相同的键,则可以使用它(准备粘贴到LINQPad):

Dictionary<string,string> fields1 = new Dictionary<string,string>();
Dictionary<string,string> fields2 = new Dictionary<string,string>();

fields1.Add("field1", "this");
fields2.Add("field1", "this");
fields1.Add("field2", "is");
fields2.Add("field2", "");
fields1.Add("field3", "a");
fields2.Add("field3", null);
fields1.Add("field4", "test");
fields2.Add("field4", "test");

var test = 
from f1 in fields1
    join f2 in fields2
    on f1.Key equals f2.Key
select (f1.Value ?? "") == (f2.Value ?? "");

test.Dump();

如果两个索引集合中的字段集具有相同的顺序,则可以使用以下内容:

string[] strings1 = { "this", "is", "a", "test" };
string[] strings2 = { "this", "", null, "test" };

var test = 
from s1 in strings1.Select((value,index) => new {value, index})
    join s2 in strings2.Select((value,index) => new {value, index})
    on s1.index equals s2.index
select (s1.value ?? "") == (s2.value ?? "");

test.Dump();

答案 7 :(得分:0)

这也可以忽略大小写

(strA ?? "").Equals(strB ?? "", StringComparison.OrdinalIgnoreCase)

答案 8 :(得分:-1)

public ActionResult<ICollection<Product>> Get()
{
    public string x = null;
    if(string.IsNullOrEmpty(x))
        return StatusCode(404, "product null");
    else
        return new Product();
}

此代码在GET请求中返回带有自定义代码和消息的错误。

这样,您可以创建全局错误处理程序。