2010-07-25 3 views
67

저는 유창한 테스트 프레임 워크에서 사용할 숫자 유형에 확장 메소드를 작성하려고합니다. 기본적으로,이 작업을 수행 할 수 : 그것은 또한 내가 잊고 다른 stringbool, 그리고 아마도 뭔가를 일치하기 때문에 숫자 유형과 일치하는 일반 제약

public static ShouldBeGreaterThan<T>(this T actual, T expected, string message) 
    where T : int || T: double || etc... 

그냥 where T : struct,하지 않습니다. 거기에 숫자 형식에만 일치하도록 할 수있는 뭔가가 있습니까? (특히 >< 연산자를 구현하는 유형이므로 비교할 수 있습니다 ... 날짜가 일치한다는 것을 의미하면 확장은 여전히 ​​중요합니다.

+6

Jon Skeet과 Mark Gravell이 다음과 같은 몇 가지 흥미로운 수업을 진행했습니다. http://www.yoda.arachsys.com/csharp/genericoperators.html –

+10

@Dan 실제로 "Marc"이지만, 실망 시키도록하겠습니다. - 소수의 사람들이 올바르게 이해할 수 있음, p –

답변

48

이 경우에는 일반 이 인터페이스를 사용하면 ShouldBeGreaterThan 질문에 대답 할 수 있으므로 CompareTo 메소드에 액세스 할 수있는 IComparable 인터페이스로 이동하십시오.

숫자 유형은 해당 인터페이스를 구현하며 문자열에서도 작동한다는 사실은 그다지 신경 쓰지 않아야합니다.

+1

이 문제는 적어도 숫자 유형에 대한보다 일반적인 연산자 인터페이스보다 나은 해결책입니다. –

+0

'.Equals()'와'.CompareTo'보다는'=='와'>'등의 사용을 허용 할 수있는 방법이 있습니까? –

5

Stackoverflow는 이런 종류의 질문에 깔려 있습니다. Take a look at this search. C#은 숫자로 제한된 제네릭 형식을 정의하는 방법을 지원하지 않습니다. 안타깝게도 가장 좋은 방법은 모든 객체에 확장 메서드를 구현하고 유형을 기반으로 스위치를 사용하거나 int, double, float 등에 대한 메서드 집합을 만드는 것입니다.

15
public static bool IsGreaterThan<T>(this T actual, T comp) where T : IComparable<T> 
{ 
    return actual.CompareTo(comp) > 0; 
} 

원하는 경우 구조체 제약 조건을 추가 할 수 있습니다.

6

필터로 사용할 INumeric과 같은 공통점이 없으므로 숫자로만 제한하기는 어렵습니다. 사실, 나는 여기서 가장 쉬운 접근법은 이 아니며이 제약 조건을 주장하고 메서드 내에서 Comparer<T>.Default.Compare을 사용합니다.

이 inbuilt 유형은 일반 IComparable<T>과 비 일반 IComparable을 모두 지원하며 ref 유형, 값 유형 및 해제 사용을 Nullable<T>을 통해 지원합니다. 전체 운영자 사용에 대한

, 당신은 정말이 (오히려 인터페이스와) 연산자를 사용하려는 경우 유용 할 수 있습니다 MiscUtil's Operator classGreaterThan 등을 확인합니다. 그것은 또한 내가 숫자 제약에 얻을 수있는 가장 가까운입니다 Add

+0

Marc Gravell은 "숫자로만 제한하는 것은 어렵습니다 **"라고 말했지만 실행 시간과 컴파일 시간 모두 ** ** 가능합니다. "제네릭 메서드를 숫자 형식으로 제한하는 제약이 있습니까?" question.https : //stackoverflow.com/questions/32664/is-there-a-constraint-that-restricts-my-generic-method-to-numeric-types –

+1

@Erez는 효과가 있지만 사망합니다. 성능이 중요한 코드 - 많은 복싱 및 유형 검사. C# 7.2-C# 8.0의 어느 곳에서 우리는 generics에이 기능을 훨씬 더 효율적으로 추가 할 가능성이 있습니다. –

+0

Microsoft에서 지원할 때까지 기다릴 수 없습니다. –

38
where T : struct, 
      IComparable, 
      IComparable<T>, 
      IConvertible, 
      IEquatable<T>, 
      IFormattable 

같은 다른 사업자에 대한 액세스를 제공합니다. 모든 숫자 유형은이 5 개의 인터페이스를 구현하지만 IFormattable은 bool에 의해 구현되지 않으며 문자열은 참조 유형이므로 적용 할 수 없습니다.

예를 들어 DateTime을 구현하는 다른 몇 가지 기능이 있으므로 실제로 필요하지는 않지만 원하지 않는 인스턴스화가 많이 발생하지 않습니다.

+0

이것으로도 일반적인 수학 연산을 사용할 수 없습니다. '연산자'== '는'T '및'부동 '형식의 피연산자에 적용 할 수 없습니다. –