我的一位高级同事在他的代码中做了一些非常奇怪的事情。
不是检查变量是否为null,而是检查类型。因为
null是FooType
实际上返回false,这有效。
public class Foo
{
private string _bar = null;
public string Bar
{
get
{
// strange way to check for null
return (_bar is string) ? _bar : "";
}
set { _bar = value; }
}
}
我认为这是错误的编码,Resharper似乎同意我的看法。有没有理由以这种方式写支票?
这是检查变量的有效方法吗?或者这可以被认为是不好的风格,甚至可能在某些特殊情况下有害?
除非我确定这实际上没有意义,否则我不想与他对抗。
答案 0 :(得分:10)
这不是一个好方法。更好的方法是:
return _bar ?? string.Empty;
当您阅读同事代码时他是否正在寻找空值?不,那不是一个好选择。也许“is”运算符首先要做的只是检查null然后返回false。因此,自己做到这一点变得更加清洁。或者只使用null-coalescing operator
答案 1 :(得分:3)
我认为这段代码完全令人困惑,永远不会使用它。 _bar
被声明为string
,因此此类型检查只是让人们不理解代码。
答案 2 :(得分:3)
return _bar ?? "" ;
当我需要做这样的事情时,我有一个小班来处理这些细节:
public class DefaultableValue<T>
{
private T m_Value = default(T);
public T Value
{
get
{
if (IsInvalidPredicate(m_Value))
{
m_Value = IfDefaultValueFunc();
}
return m_Value;
}
}
private Predicate<T> IsInvalidPredicate { get; set; }
private Func<T> IfDefaultValueFunc { get; set; }
public static implicit operator T(DefaultableValue<T> property)
{
return property.Value;
}
public DefaultableValue(Predicate<T> isInvalidPredicate,Func<T> ifDefaultFunc)
: this(default(T), isInvalidPredicate, ifDefaultFunc)
{
}
public DefaultableValue(T initValue, Predicate<T> isInvalidPredicate, Func<T> ifDefaultFunc)
{
this.m_Value = initValue;
this.IsInvalidPredicate = isInvalidPredicate;
this.IfDefaultValueFunc = ifDefaultFunc;
}
}
然后我的班级看起来像
class Test
{
DefaultableValue<string> AString { get; set; }
public Test(string initialValue)
{
this.AString = new DefaultableValue<string>(initialValue,
(value) => string.IsNullOrWhiteSpace(value),
() => string.Empty);
}
}
....
var test = new Test(null);
var someString = test.AString; // = "" not null
答案 3 :(得分:0)
如果声明上述公共属性返回object
而不是string
,则上述内容可能有意义。但是,因为它返回字符串,所以这种类型的检查没有意义。如果你想返回一个空字符串,你可以这样做:
public class Foo
{
private string _bar = null;
public string Bar
{
get
{
return (String.IsNullOrWhitespace(_bar)) ? "": _bar;
}
set { _bar = value; }
}
}