使用C#和.NET 3.5,处理这种情况的最佳方法是什么。我有数百个字段可以从各种来源(主要是字符串)进行比较。有时,源将字符串字段返回为null,有时为空。当然,有时字段中会有文字。我当前对strA!= strB的比较并没有削减它,因为例如strA为null且strB为“”。我知道我可以做string.IsNullOrEmpty导致双重比较和一些丑陋。有没有更好的方法来处理这个?我认为扩展方法,但你不能扩展运算符。
我想我正在寻找一种性感的方式来做到这一点。
答案 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请求中返回带有自定义代码和消息的错误。
这样,您可以创建全局错误处理程序。