2010-02-02 5 views
8

해당 값 형식의 값이 기본값인지 여부를 확인할 수 있기를 원합니다. 이상적으로, 내가 말할 싶습니다제네릭 형식을 사용하여 기본값 확인

DoSomething<TValue>(TValue value) { 
    if (value == default(TValue)) { 
     ... 
    } 
} 

그러나, 컴파일러는 TValue 및 TValue에 == 비교를 할 수 없다는 불평. 지금까지 생각해 낸 최선의 해결 방법은

DoSomething<TValue>(TValue value) { 
    if (value == null || value.Equals(default(TValue))) { 
     ... 
    } 
} 

더 자세히 설명해 드리겠습니다.

답변

37
public bool EqualsDefaultValue<T>(T value) 
{ 
    return EqualityComparer<T>.Default.Equals(value, default(T)); 
} 
4

클래스 제약 조건을 던집니다. 그러면 작동합니다.

public void Test<T>(T instance) where T : class 
{ 
    if (instance == default(T)) 
    { 

    } 
} 

또는 값 유형 만 원할 경우이 작업을 수행 할 수 있습니다.

public void Test<T>(T instance) where T : struct, IEquatable<T> 
{ 
    if (instance.Equals(default(T))) 
    { 

    } 
} 
+4

'class' 제약 조건을 던지면'null'을 체크 할 수 있습니다 ... –

+0

@Marc -이 시점에서 문제가됩니다. 선호도. – ChaosPandion

+0

나는 값과 클래스 유형을 포함한 모든 유형에 대해이 작업을 수행하기를 희망합니다. – StriplingWarrior

1

귀하의 문제는 (제한 없음)와 함께 genric 유형은 어떤 유형의 "컴파일 가능한"이어야한다는 것입니다. 모든 유형에 == 연산자가있는 것은 아니므로 코드가 컴파일되지 않습니다.

해결 방법 중 하나는 클래스 제약 조건을 추가하는 것입니다.하지만 기본값 (TValue)을 사용하면 코드가 다른 유형과 함께 작동하기를 바랍니다. (그렇지 않으면 단지) 대신 기본 (TValue의 널 (null)을 사용한다. 하나의 해결책은 브라이언 와트

bool DoSomething<TValue>(TValue value) { 
    return EqualityComparer<TValue>.Default.Equals(value, default(TValue)); 
} 

을 제안하거나에 추가 확장 방법

bool IsDefault<TValue>(this TValue value) { 
    return EqualityComparer<TValue>.Default.Equals(value, default(TValue)); 
} 
0

에서 그것을 마무리 할 수있는 것과 유사한 일 수 있습니다 우리 모두는 단지 만들고 엄청나게 작은 시간을 유지하기 위해 사랑

static public class MyGenericHelper 
{ 
    static public bool EqualsByValue<T>(T x, T y) 
    { 
     return EqualityComparer<T>.Default.Equals(x, y); 
    } 

    static public bool EqualsByReference<T>(T x, T y) 
    { 
     if (x is ValueType) return EqualityComparer<T>.Default.Equals(x, y) // avoids boxing 

     return Object.ReferenceEquals(x, y); 
    } 
} 

: 답변 여기에 게시, 우리는 또한 우리가 값 또는 참조 평등을 원하는 경우 지정할 수 있어야한다고 생각합니다 그와 같은 엘 퍼 방법은 :->

+0

가독성과 성능면에서'typeof (T) .IsValueType'은'x is ValueType'보다 더 낫습니다. 내가 잘못? – StriplingWarrior

+1

때때로 가독성은 때로는 맛의 문제입니다. : typeType (T) .IsValueType'은 매우 무거운'Type' 인스턴스를 검색해야하기 때문에 -> ...'x는 ValueType'입니다. 직관적으로 "필자는 더 빨리"느껴집니다. 그리고 Reflector는'.IsValueType' property는 RuntimeType으로 구현 된 가상 메소드를 호출하여 궁극적으로 뭔가 extern을 호출합니다. 그런데 내가 판단 할 사람은 내가 내부자가 아니야. 심지어 같은 지침으로 컴파일 될 수도 있습니다. 아마도 그것은 좋은 새로운 질문입니다. ;-) ... 또는 중요한 경우 성능 테스트를 직접 수행 할 수도 있습니다. – herzmeister

+0

그것은 중요하지 않지만, 나는 호기심이 많았습니다. 그래서 나는 빠른 테스트를했고 당신 말이 맞습니다! 'x는 ValueType입니다. '는 약 3 분의 1이 소요됩니다. – StriplingWarrior

관련 문제