Null 허용 유형: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) { }
Update 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
그것은 a입니다 참조 유형, value
비교됩니다 null
( default(T)
), 그렇지 않으면, if T
a value type
, 두 배라고하자. default(t)
BOOL은 0D입니다 false
, char '\0'
등등...
나는 받아 들인 답변을 매우 좋아하지만 완전성을 위해 이 옵션도 언급해야 한다고 생각합니다.
if (item.Rate.GetValueOrDefault() == 0) { }
이 솔루션
- 별도의 방법이 필요하지 않으며,
- 다른 모든 옵션보다 빠릅니다. GetValueOrDefault는 단일 필드 읽기 작업입니다.¹ 및
- 보다 쉽게 읽힌다
((item.Rate ?? 0) == 0)
(이것은 취향의 문제일 수도 있지만).
¹ 그러나 이러한 종류의 미세 최적화는 아무런 변화를 가져올 가능성이 없기 때문에 결정에 영향을 주어서는 안 됩니다.
이것은 실제로 제네릭을 사용하여 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));
}
노트 우리는 값 유형이나 structs를 다루기 때문에 NULL의 기본값 (t)을 확인할 필요가 없습니다! 이것은 또한 우리가 t valuetocheck가 null이 아니라고 가정 할 수 있음을 의미합니다. 여기를 기억하십니까? 속기가 많을 수 있습니다u003CT> 따라서 확장을 Nullable에 추가함으로써u003CT> 우리는 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))
더 좋은 방법이 있습니까?
글쎄, 당신이 정말로 더 나은 방법을 찾고 있다면, 당신은 아마도 비율 위에 다른 추상화 계층을 추가 할 수 있습니다. 여기에 널리 잡을 수있는 디자인 패턴을 사용하여 제가 생각해 낸 것이 있습니다.
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) { } } }
코드 샘플이 실패합니다. obj가 null이면 obj.tostring ()은 널 참조 예외를 초래합니다. 프로세스를 단단하고 도우미 기능이 시작될 때 Null OBJ를 확인합니다. 실제 질문에 관해서는 NULL 또는 0을 확인하는 유형은 무엇입니까? 문자열에는 훌륭한 isnullorempty 함수가 있습니다. 이것은 나에게 int에서 isnullorzero 메소드를 구현하기 위해 확장 방법을 잘 사용하는 것 같습니다. 유형.
편집 : '?'를 기억하십시오. 불가능한 유형의 컴파일러 설탕 일 뿐이므로 PARM처럼 inullible을 취한 다음 JSUT를 NULL (PARM == NULL)과 비교할 수 있으며 NULL이 0과 비교하지 않으면 비교할 수 있습니다.
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);}}
}
문자열의 경우 항상 사용할 수 있습니다.
String.IsNullOrEmpty(str)
대신에:
str==null || str==""