2009-06-13 3 views
1

내가 인터페이스 사업자을 포함 할 수 없습니다 것을 알고 과부하,하지만 난 을 필요로 할 수있는 방법이/+와/사업자 특정 클래스에 의해 구현 될 것입니다 컴파일러에게?C#을 요구하는 운영자

나는 이런 식으로 뭔가를 할 :

 
public class AutoAverage<T> where T:(overloads + and /) 
{ 
    private List<T> history ; // 10-20 values 

    public T NextAvg(T newValue) 
    { 
    // implementation wants to push newValue 
    // into history, then sum 
    // values in history and return an average 
    } 
} 
+2

자주 요청되는 기능입니다. 작동 시키려면 CLR에서 상당한 작업이 필요하지만 분명히 그들의 레이더에 있습니다. 가상 버전의 향후 버전에는 가능한 기능이지만 약속은 없습니다. –

답변

3

불행하게도, 그 C#으로하실 수 없습니다.

1

나는 이런 식으로 뭔가를 시도 할 것 : 이런 경우에

interface ISumT<T> 
{ 
    /// <summary> 
    /// the sum method adds rhs to this and returns the result 
    /// </summary> 
    /// <remark> 
    /// use a interface (i.e. ISumT) 
    /// with a method (i.e. sum) 
    /// because "where" doesn't support operators 
    /// </remark> 
    T sum(T rhs); 
} 

public class AutoAverage<T> where T : ISumT<T> 
{ 
    public T NextAvg(T newValue) 
    { 
    // can assume that T implements the sum method 
    } 
} 
+0

거의 유일한 방법. – mquander

+0

... 모든 프리미티브에 대해 ISumT를 구현하는 클래스를 만드는 것이 실제로 지루한 일임이 밝혀졌습니다! – bobobobo

3

때때로,

public class AutoAverage<T> 
{ 
    public AutoAverage(Func<T, T, T> sum, Func<T, T, T> divide) { ... 

그리고 사용량 :

나는 생성자에 람다를 전달합니다
var autoAverage = new AutoAverage((x, y) => x + y, (x, y) => x/y); 
// ... use it ... 

이와 같이 바이너리 연산을 수행 할 때 약간 엉망입니다. (예를 들어, 단일 인수 함수에 자주 사용했습니다. 단위 변환), 단순성의 장점이 있습니다.

귀하의 경우에 적합한 솔루션인지 여부는 AutoAverage를 구성하는 빈도에 달려 있습니다. 하나 또는 두 개의 장소 (각 T에 대해) 만 만들면 람다를 지나치지 않을 것입니다. 만약 당신이 그것을 여러 곳으로 구성한다면, 람다는 너무 편안하게 복제 될 것입니다.

+0

+1 측면 생각. – ChrisW

1

MiscUtil 런타임에 generic operator support을 제공하기 위해 .NET 3.5을 사용하여 (Sum, Average, 등) 내장 일반적인 집계 기능을 가지고 있습니다.

또한 C# 4.0에서는 dynamic (연산자를 지원함)을 통해이 작업을 수행 할 수 있지만 위의 방법은 대개 더 빠릅니다 (간접 참조가 적음).