检查类型而不是null是一个合理的选择吗?

时间:2012-05-03 17:34:10

标签: c# .net null

我的一位高级同事在他的代码中做了一些非常奇怪的事情。

不是检查变量是否为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似乎同意我的看法。有没有理由以这种方式写支票?

这是检查变量的有效方法吗?或者这可以被认为是不好的风格,甚至可能在某些特殊情况下有害?

除非我确定这实际上没有意义,否则我不想与他对抗。

4 个答案:

答案 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; } 
    } 
}