¿Es la verificación de tipo en lugar de nulo una opción razonable?

Uno de mis compañeros de trabajo (senior) hace algo realmente extraño en su código.

En lugar de comprobar si una variable es nula, comprueba el tipo. Y porqué

nulo es FootType

en realidad devuelve falso, esto funciona.

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

Creo que esta es una mala codificación y Resharper parece estar de acuerdo conmigo. ¿Hay alguna razón para escribir el cheque de esta manera?

¿Es esta una forma válida de verificar la variable? ¿O esto puede considerarse de mal estilo o incluso dañino en algunos casos especiales?

No quiero confrontarlo a menos que esté seguro de que esto realmente no tiene sentido.

preguntado el 03 de mayo de 12 a las 18:05

¿Su compañero de trabajo principal tiene antecedentes de vb por casualidad? -

Pienso que si. O vbscript al menos. ¿Es esta una expresión común en VB? -

Las versiones anteriores de VB carecían de muchos operadores abreviados útiles, por lo que la anterior habría sido la versión abreviada. -

4 Respuestas

Esta no es una buena manera. Una mejor manera sería simplemente:

return _bar ?? string.Empty;

¿Está claro cuando lee el código de sus colegas que está buscando nulos? No, entonces no es una buena elección. Probablemente, lo que hará primero el operador "es" es simplemente verificar si hay nulo y luego devolver falso. Por lo tanto, se vuelve mucho más limpio hacerlo usted mismo. O simplemente use el operador de fusión nula

contestado el 03 de mayo de 12 a las 18:05

"¿Está claro cuando lee el código de sus colegas que está buscando nulos?" No, pero ¿qué más podría estar comprobando cuando la variable que comprueba claramente es una cadena? - magnático

@atticae ¿Eso lo convierte en un uso válido? - Oskar Kjellin

Lo siento, no entiendo. Asumí que solo podría estar verificando nulo porque la variable que verifica ("_bar" arriba) siempre es de tipo cadena. - magnático

En realidad, el operador de IL detrás is y as es lo mismo, "isinst", que actúa más o menos como as; verifica si la referencia emergente es una instancia de un identificador de clase pasado, y empuja la instancia si es verdadera, nula si no. as usos isinst casi textualmente, mientras is además, comprueba que el resultado de isinst empujado es nulo. - keiths

@KeithS Eso hace que este uso sea aún peor en términos de rendimiento: Oskar Kjellin

Creo que este código es completamente confuso y nunca lo usaría. _bar es declarado como un string por lo que esta verificación de tipo solo le ruega a la gente que no entienda el código.

contestado el 03 de mayo de 12 a las 18:05

Sí, eso es un poco extraño. ¿Por qué no simplemente escribir:

return _bar ?? "" ;

Cuando necesito hacer algo como esto, tengo una pequeña clase para manejar estos detalles:

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

Entonces mi clase parece

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

contestado el 03 de mayo de 12 a las 18:05

Hay demasiadas personas por ahí que nunca han oído hablar de ??. - kendall frey

si la propiedad pública anterior fue declarada para volver object en lugar de string, lo anterior podría tener sentido. Sin embargo, debido a que está devolviendo una cadena, ese tipo de verificación no tiene sentido. Si desea devolver una cadena vacía, podría hacer algo como esto:

public class Foo 
{ 
    private string _bar = null; 

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

contestado el 03 de mayo de 12 a las 18:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.