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

本文关键字:一个 选择 类型 是否是 null 检查 | 更新日期: 2023-09-27 18:33:00

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

他不是检查变量的 null,而是检查类型。因为

null 是 FooType

实际上返回假,这有效。

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似乎同意我的观点。有什么理由以这种方式写支票吗?

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

不想面对他,除非我确信这实际上没有意义。

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

这不是

一个好方法。更好的方法是:

return _bar ?? string.Empty;

当您阅读同事的代码时,是否清楚他正在寻找空值?不,那么这不是一个好的选择。可能"is"运算符首先要做的只是检查 null,然后返回 false。因此,自己做这件事会变得干净得多。或者只使用 null 合并运算符

我认为

这段代码完全令人困惑,永远不会使用它。 _bar被声明为string所以这种类型检查只是乞求人们不理解代码。

是的,这有点奇怪。为什么不直接写:

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

如果上述公共属性被声明为返回object而不是string,则上述内容可能是有意义的。但是,由于它返回字符串,因此这种类型的检查没有意义。如果要返回一个空字符串,可以执行以下操作:

public class Foo 
{ 
    private string _bar = null; 
    public string Bar 
    { 
        get 
        {  
            return (String.IsNullOrWhitespace(_bar)) ? "": _bar; 
        } 
        set { _bar = value; } 
    } 
}