developer tip

Nullable 형식 : C #에서 null 또는 0을 확인하는 가장 좋은 방법

copycodes 2020. 10. 25. 12:27
반응형

Nullable 형식 : C #에서 null 또는 0을 확인하는 가장 좋은 방법


저는 여러 곳에서 다음 사항을 확인하는 프로젝트를 진행하고 있습니다.

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

무엇보다 호기심으로 두 사례를 확인하는 가장 좋은 방법은 무엇입니까?

다음과 같은 도우미 메서드를 추가했습니다.

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

더 좋은 방법이 있습니까?


나는 좋아한다 if ((item.Rate ?? 0) == 0) { }

업데이트 1 :

다음과 같은 확장 메서드를 정의 할 수도 있습니다.

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

다음과 같이 사용하십시오.

if(item.IsNullOrValue(0)){} //하지만 당신은 그것으로부터 많은 것을 얻지 못합니다


제네릭 사용 :

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

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

만약 T그것의 참조 형 , value비교한다 null( default(T)), 그렇지 않은 경우 TA는 value type,의 두 번 가정 해 봅시다 default(t)부울이 들어 0D입니다 false문자이기 때문이다, '\0'등등 ...


나는 받아 들여지는 대답을 아주 좋아하지만 완전성을 위해이 옵션도 언급해야한다고 생각합니다.

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

이 솔루션

  • 추가 방법이 필요하지 않습니다.
  • GetValueOrDefault는 단일 필드 읽기 작업 ¹ 이므로 다른 모든 옵션보다 빠릅니다.
  • 보다 쉽게 ​​읽습니다 ((item.Rate ?? 0) == 0)(하지만 이것은 취향의 문제 일 수 있습니다).

¹하지만 이러한 종류의 마이크로 최적화는 아무런 차이가 없을 가능성이 높기 때문에 결정에 영향을주지 않습니다.


이것은 Generics를 사용하는 Freddy Rios의 대답의 확장에 불과합니다.

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

참고 값 유형이나 구조체를 다루기 때문에 null에 대해 default (T)를 확인할 필요가 없습니다! 이것은 또한 T valueToCheck가 null이 아니라고 안전하게 가정 할 수 있음을 의미합니다. 여기 T 기억 나? 속기 Nullable <T>이므로 Nullable <T>에 확장을 추가하면 int ?, double ?, bool? 기타

예 :

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

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

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

사용에 동의합니다 ?? 운영자.

문자열을 다루는 경우 if (String.IsNullOrEmpty (myStr))


더 좋은 방법이 있습니까?

글쎄, 만약 당신이 정말로 더 나은 방법을 찾고 있다면 아마도 Rate 위에 또 다른 추상화 계층을 추가 할 수있을 것입니다. Nullable Design Pattern을 사용하여 방금 생각해 낸 것이 있습니다.

시스템 사용;
System.Collections.Generic 사용;

네임 스페이스 NullObjectPatternTest
{
    공개 수업 프로그램
    {
        public static void Main (string [] args)
        {
            var items = 새 목록
                            {
                                새 항목 (RateFactory.Create (20)),
                                새 항목 (RateFactory.Create (null))
                            };

            PrintPricesForItems (items);
        }

        private static void PrintPricesForItems (IEnumerable items)
        {
            foreach (항목의 var 항목)
                Console.WriteLine ( "항목 가격 : {0 : C}", item.GetPrice ());
        }
    }

    공용 추상 클래스 ItemBase
    {
        public abstract Rate Rate {get; }
        public int GetPrice ()
        {
            // Rate == 0인지 Rate == null인지 확인할 필요가 없습니다.
            return 1 * Rate.Value;
        }
    }

    공용 클래스 Item : ItemBase
    {
        개인 읽기 전용 Rate _Rate;
        public override Rate Rate {get {return _Rate; }}
        public Item (Rate rate) {_Rate = rate; }
    }

    공개 봉인 클래스 RateFactory
    {
        public static Rate Create (int? rateValue)
        {
            if (! rateValue || rateValue == 0) 
                return new NullRate ();
            return new Rate (rateValue);
        }
    }

    공개 클래스 비율
    {
        public int Value {get; 세트; }
        public virtual bool HasValue {get {return (Value> 0); }}
        public Rate (int value) {Value = value; }
    }

    공용 클래스 NullRate : 비율
    {
        public override bool HasValue {get {return false; }}
        public NullRate () : base (0) {}
    }
}

코드 샘플은 실패합니다. obj가 null이면 obj.ToString ()은 null 참조 예외를 발생시킵니다. 프로세스를 단축하고 도우미 함수 시작시 null obj를 확인합니다. 실제 질문에 관해서는 null 또는 0을 확인하는 유형이 무엇입니까? String에는 훌륭한 IsNullOrEmpty 함수가 있습니다. 이것은 확장 메서드를 사용하여 int에서 IsNullOrZero 메서드를 구현하는 데 유용 할 것 같습니다. 유형.

Edit: Remember, the '?' is just compiler sugar for the INullable type, so you could probably take an INullable as the parm and then jsut compare it to null (parm == null) and if not null compare to 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);}}
}

Don't forget, for strings, you can always use:

String.IsNullOrEmpty(str)

Instead of:

str==null || str==""

One step further from Joshua Shannon's nice answer. Now with preventing 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));
    }
}

참고URL : https://stackoverflow.com/questions/633286/nullable-types-best-way-to-check-for-null-or-zero-in-c-sharp

반응형