我经常找到理由比较C#中的两个值或对象 - 通常是不同的类型 - 我发现自己对我写的代码不满意。
代码最终看起来(对我而言)冗长且不清楚,我经常最终感觉需要添加一条评论“//检查它们是否相等”。
(我常常责怪没有像我在Groovy中看到的那样没有nullsafe-dereference运算符的事实。)
在最近的一个例子中,我有两个变量:
string s;
int? i;
假设我想比较它们,这样如果它们“明显相等”,我就能做点什么
如果其中任何一个,我将它们定义为“显然相等”:
a)int?不包含数字,字符串为null,否则...
b)如果你写出int的数值,字符串是你得到的?以简单/无格式的方式。
[注意,在这种情况下,我实际上并不担心数字1234是否被认为等于字符串“01234”或“1234.00”(或者实际上是“1234,00”,如果你是我认为的外国人) 。
只要“1234” 被认为是相等的,并且(例如)“1233 + 1”和“1234z”不是,您就可以灵活地使用它们。<登记/>
你是否也可以灵活调整int?不包含数字的行为被视为等于空字符串。]
所以,我想要一些[清晰/简单/简短 - 对主观性道歉]表达式放入我的“if”条件,它将按照上面的要求执行检查,绝对不会抛出异常。
我有什么选择?
(如果有人想将他们的解决方案与其他语言中更容易表达的方式进行比较,请随意。了解绿叶草的位置总是有用的。)
更新
我自己的代码归结为类似......
if (s == (i.HasValue ? i.Value.ToString() : null))
实际上看起来并不那么糟糕,因为s和i在其他对象上没有有意义的命名属性。
[但是,我真的不喜欢在那里留下“==”比较因为(虽然它适用于字符串因为字符串实习和/或操作符覆盖等),它通常会检查引用相等性,对吗?所以我考虑用string.Equals替换它......但是阅读起来更加可怕。]
当你还必须检查父对象(存在“有意义的属性”)为null时,代码就会变得如此冗长 - 这就是我发布问题时的想法,我想。 我想看看其他人是否有我遗失的东西。
我真的希望能够简单地检查积极的情况并让其他一切评估为假(没有抛出可见的异常)。所以......
if ( (someObject.s == null && someOther.i == null)
||
(int.Parse(someObject.s) == someOther.i) )
如果所有可能的(null-ref / parse)异常都可以被静默强制为false,那么或者类似的非常“happy”。
我想我的老年时代就太懒了......
答案 0 :(得分:3)
public static bool ObviouslyEquals<T>(this string s, T? t) where T: struct
{
if (s == null && !t.HasValue)
return true;
if (s == null || !t.HasValue)
return false;
return s.Equals(t.Value.ToString());
}
string s;
int? i;
if (s.ObviouslyEquals(i))...
答案 1 :(得分:0)
如果有一个值“i”永远不会(假设为-1),你可以使用这样的东西:
((object)i ?? -1).ToString() == s
但这不适用于特殊数字格式。 所以这可能会有所帮助:
int x;
!((i == null) != (s == null) || i != null && (!ToInt32.TryParse(s, out x) || i != x))