2009-05-27 2 views
4

이렇게 할 수있는 방법이 있습니까?기본 수학 연산자를 구현하기 위해 제네릭 매개 변수를 제한하려면 어떻게합니까?

나는 T 형에 더하기, 빼기를 할 수있는 T의 컬렉션 클래스를 갖고 싶습니다. 같은 코드를 가진 몇 개의 콜렉션 대신에 T generic을 사용하고 싶습니다.

어떻게 일반 T를 제한 하시겠습니까?

예 : 컬렉션 (T의 IDoMaths)을 정의하고 싶습니다. 나는 그것이 느릴 것이라고 생각하기 때문에 명명 된 메소드를 가지고 자신 만의 정수 등 클래스를 만들고 싶지 않을 것이다. 코드의이 부분은 실제로 자주 호출되며 성능에서 병목 현상이 발생하는 경향이 있습니다.

답변

7

안타깝게도 할 수 없습니다.

implementedMiscUtil (more general article도 포함)의 일부인 해결 방법이 있습니다. 그것은 깔끔하지만 정적 유형 검사를 잃게됩니다.

dynamic x = 10.0; 
dynamic y = 3.0; 
double z = x/y; // z = 3.3333333 (double arithmetic) 

dynamic a = 10; 
dynamic b = 3; 
int c = a/b; // c = 3 (integer arithmetic) 

그냥이 오후 I : C# 4.0의 새로운 dynamic 기능 (유형 검사 손실의 측면에서)

비슷한 맥락에서

경우에만 실행 시간에 이러한 문제를 해결하기, 임의의 방법으로 연산자를 사용할 수 있습니다 이를 사용하여 Enumerable.Sum의 동적 양식을 구현했습니다. 나는 그것을 벤치마킹하려고한다. 최근에 Marc Gravell이 blog post을 작성했습니다.

VB를 사용하는 경우 후기 바인딩을 사용하려는 코드 섹션에 대해 Option Strict을 사용하지 않아도되지만 VB에서 익숙하지 않은 C#을 사용할 수 있습니다. 두려워.

+0

제네릭의 현재 구현에서 실망스러운 제한 사항입니다. Marc의 구현은 문제를 다룰 때 가장 잘 보았습니다. 이에 관련된 connect.microsoft.com에 대한 몇 가지 지원 문서가 있습니다. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?Feedback=94264 및 여기에서 찾을 수 있습니다. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID= 325177 및 여기 : http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=338861. – LBushkin

+0

동적 예제를 사용하려고 했습니까? –

+0

Doh - 고마워, 고정 :) –

4

좀 더 직관적이지만 약간의 중복성이 필요한 대체 솔루션을 원한다면 방금 시도해 볼 수 있습니다. 여기서 이점은 완전히 typesafe하다는 것입니다.

다음은 int 및 float에 대해 + 및 - 연산을 구현하는 빠른 버전입니다. 더 많은 연산을 포함하고 더 많은 기본 유형 (2 진수, 10 진수 등)을 지원하거나 사용자 정의 유형까지 지원하는 것은 자명합니다. GenericMath를 필요한 것으로 바꾸십시오.

class Program 
{ 
    static void Main(string[] args) 
    { 
     var gsInt = new GenericMath<int,IntOperators>(); 
     var gsFloat = new GenericMath<float,FloatOperators>(); 

     var intX = gsInt.Sum(2, 3); 
     var floatX = gsFloat.Sum(2.4f, 3.11f); 
    } 
} 

interface IOperators<T> 
{ 
    T Sum(T a, T b); 
    T Difference(T a, T b); 
} 

sealed class IntOperators : IOperators<int> 
{ 
    public int Sum(int a, int b) { return a + b; } 
    public int Difference(int a, int b) { return a - b; } 
} 

sealed class FloatOperators : IOperators<float> 
{ 
    public float Sum(float a, float b) { return a + b; } 
    public float Difference(float a, float b) { return a + b; } 
} 

class GenericMath<T,Y> 
    where Y : IOperators<T>, new() 
{ 
    private readonly static Y Ops = new Y(); 

    public T Sum(T a, T b) 
    { 
     return Ops.Sum(a, b); 
    } 

    public T Difference(T a, T b) 
    { 
     return Ops.Difference(a, b); 
    } 
} 
+0

전체 공개 - IOperators 구현 유형을 일반 수학 연산을 수행 할 클래스의 인스턴스에 제공해야합니다. – LBushkin

+0

+1, 짧은 단정하고 멋지게 작동합니다. – smirkingman

관련 문제