Pergunta

Eu estou trabalhando em um projeto onde eu acho que eu estou verificando o seguinte em muitos, muitos lugares:

if(item.Rate == 0 || item.Rate == null) { }

mais como uma curiosidade do que qualquer coisa, qual é a melhor maneira de verificar para ambos os casos?

Eu adicionei um método auxiliar que é:

public static bool nz(object obj)
{
    var parsedInt = 0;
    var parsed = int.TryParse(obj.ToString(), out parsedInt);
    return IsNull(obj) || (parsed && parsedInt == 0);
}

Existe uma maneira melhor?

Foi útil?

Solução

Eu gosto if ((item.Rate ?? 0) == 0) { }

Update 1:

Você também pode definir um método de extensão como:

public static bool IsNullOrValue(this double? value, double valueToCheck)
{
    return (value??valueToCheck) == valueToCheck;
}

E usá-lo como este:

if(item.IsNullOrValue(0)){} // mas você não tem muito com ele

Outras dicas

Usando genéricos:

static bool IsNullOrDefault<T>(T value)
{
    return object.Equals(value, default(T));
}

//...
double d = 0;
IsNullOrDefault(d); // true
MyClass c = null;
IsNullOrDefault(c); // true

Se T é uma tipo de referência , value serão comparados com null (default(T)), caso contrário, se T é um value type, digamos dupla, default(t) é 0d, para bool é false, por caractere é '\0' e assim por diante ...

Embora eu gosto bastante a resposta aceita, eu acho que, para ser completo, esta opção deve ser mencionado, bem como:

if (item.Rate.GetValueOrDefault() == 0) { }

Esta solução


¹ Isto não deve influenciar a sua decisão, no entanto, uma vez que estes tipos de micro-otimização não são susceptíveis de fazer qualquer diferença.

Isto é realmente apenas uma expansão de resposta aceita Freddy Rios' usando apenas Genéricos.

public static bool IsNullOrDefault<T>(this Nullable<T> value) where T : struct
{
    return default(T).Equals( value.GetValueOrDefault() );
}

public static bool IsValue<T>(this Nullable<T> value, T valueToCheck) where T : struct
{
    return valueToCheck.Equals((value ?? valueToCheck));
}

NOTA não precisa verificar default (T) para nula uma vez que estamos lidando tanto com tipos de valor ou estruturas! Isso também significa que nós podemos seguramente assumir T valueToCheck não vai ser nulo; Lembre-se aqui que T? é uma abreviação Nullable -lo adicionando a extensão para Nullable obtemos o método em int ?, dupla ?, bool? etc.

Exemplos:

double? x = null;
x.IsNullOrDefault(); //true

int? y = 3;
y.IsNullOrDefault(); //false

bool? z = false;
z.IsNullOrDefault(); //true

Eu concordo com o uso do ?? operador.

Se você está lidando com cordas usar se (String.IsNullOrEmpty (myStr))

Existe uma maneira melhor?

Bem, se você está realmente procurando uma maneira melhor, provavelmente você pode adicionar outra camada de abstração em cima Rate. Ora aqui está algo que eu só vim com usando Nullable Design Pattern.

using System;
using System.Collections.Generic;

namespace NullObjectPatternTest
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var items = new List
                            {
                                new Item(RateFactory.Create(20)),
                                new Item(RateFactory.Create(null))
                            };

            PrintPricesForItems(items);
        }

        private static void PrintPricesForItems(IEnumerable items)
        {
            foreach (var item in items)
                Console.WriteLine("Item Price: {0:C}", item.GetPrice());
        }
    }

    public abstract class ItemBase
    {
        public abstract Rate Rate { get; }
        public int GetPrice()
        {
            // There is NO need to check if Rate == 0 or Rate == null
            return 1 * Rate.Value;
        }
    }

    public class Item : ItemBase
    {
        private readonly Rate _Rate;
        public override Rate Rate { get { return _Rate; } }
        public Item(Rate rate) { _Rate = rate; }
    }

    public sealed class RateFactory
    {
        public static Rate Create(int? rateValue)
        {
            if (!rateValue || rateValue == 0) 
                return new NullRate();
            return new Rate(rateValue);
        }
    }

    public class Rate
    {
        public int Value { get; set; }
        public virtual bool HasValue { get { return (Value > 0); } }
        public Rate(int value) { Value = value; }
    }

    public class NullRate : Rate
    {
        public override bool HasValue { get { return false; } }
        public NullRate() : base(0) { }
    }
}

Exemplo de código Você irá falhar. Se obj é nulo, em seguida, o obj.ToString () vai resultar em uma excepção referência nula. Eu curto cortar o processo e verificar a existência de um obj nula no início de sua função auxiliar. Quanto à sua pergunta real, qual é o tipo que você está verificando para nulo ou nulo? Na seqüência há uma grande função IsNullOrEmpty, parece-me que este seria um grande uso de métodos de extensão para implementar um método IsNullOrZero na int? tipo.

Edit: Lembre-se, o '? é apenas compilador açúcar para o tipo INullable, então você poderia provavelmente ter um INullable como o parm e depois jsut compará-lo com nula (parm == null) e se não nulo comparar a zero.

public static bool nz(object obj)
{
    return obj == null || obj.Equals(Activator.CreateInstance(obj.GetType()));
}
class Item{  
 bool IsNullOrZero{ get{return ((this.Rate ?? 0) == 0);}}
}

Não esqueça, para cordas, você sempre pode usar:

String.IsNullOrEmpty(str)

Em vez de:

str==null || str==""

Um passo mais longe agradável Joshua de Shannon resposta . Agora com a prevenção boxing / unboxing :

public static class NullableEx
{
    public static bool IsNullOrDefault<T>(this T? value)
        where T : struct
    {
        return EqualityComparer<T>.Default.Equals(value.GetValueOrDefault(), default(T));
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top