연산자를 오버로드 한 형식 (예 : 빼기 연산자) 만 허용하는 일반 메서드를 사용하려면 어떻게해야합니까? 제약 조건으로 인터페이스를 사용했지만 인터페이스에 연산자 오버로딩을 사용할 수 없습니다..NET 제네릭에서 오버로드 된 연산자 제약 조건에 대한 솔루션
이것을 달성하는 가장 좋은 방법은 무엇입니까?
연산자를 오버로드 한 형식 (예 : 빼기 연산자) 만 허용하는 일반 메서드를 사용하려면 어떻게해야합니까? 제약 조건으로 인터페이스를 사용했지만 인터페이스에 연산자 오버로딩을 사용할 수 없습니다..NET 제네릭에서 오버로드 된 연산자 제약 조건에 대한 솔루션
이것을 달성하는 가장 좋은 방법은 무엇입니까?
즉각적인 대답은 없습니다. 연산자는 정적이며 제약 조건으로 표현할 수 없습니다. 기존의 프리미티브는 특정 인터페이스를 구현하지 않습니다 (IComparable [<T>]와 비교하여보다 크거나 같음을 에뮬레이션하는 데 사용할 수 있음).
그러나; 당신은 그냥 작업 할 경우, 다음 .NET 3.5에 내가 함께 넣어 가지고
... 몇 가지 옵션이 있습니다 제네릭과 운영에 효율적이고 간단하게 액세스 할 수 있습니다 라이브러리 here - 같은 :
T result = Operator.Add(first, second); // implicit <T>; here
가 이것은 C# 4.0, 또한 MiscUtil
의 일부로서 다운로드 될 수 있으며, 이는 dynamic
통해 가능해진다 :
static T Add<T>(T x, T y) {
dynamic dx = x, dy = y;
return dx + dy;
}
또한 (한 지점에서) .NET 2.0 버전을 가지고 있었지만 테스트가 덜 까다 롭습니다. 다른 옵션은
interface ICalc<T>
{
T Add(T,T)()
T Subtract(T,T)()
}
등과 같은 인터페이스를 만드는 것입니다,하지만 당신은 지저분 모든 방법을 통해 ICalc<T>;
을 통과해야합니다.
.NET 4.0에서 동적 기능을 사용하기를 좋아합니다. 그러나 런타임시 더 많은 작업을해야하기 때문에 성능에 영향을 미칠 수 있다는 점을 지적하는 것이 중요합니다. 나는 그것이 얼마나 많은 영향을 미치는지 알기를 원할 것이다. 나는 생각하기에 벤치마킹이 필요하다. –
벤치 마크 완료. 여기에서 코드를 시도하십시오. http://social.msdn.microsoft.com/Forums/en-US/vs2010ctpvbcs/thread/287db1b9-c135-40bc-a1c5-a8a51efbfc65 –
나는 (.NET 3.5 용) 라이브러리를 사용해 보았습니다. 그리고 나는 다음의 라인이 작동하지 않는 이유가 무엇인지 질문한다 : MiscUtil.Operator.Add ("A", "B"); 제 생각에 "AB"가 반환됩니다. – Malki
IL이 실제로 이것을 상당히 잘 처리 할 수 있다는 것을 알았습니다. 전의.
ldarg.0
ldarg.1
add
ret
일반 메서드로 컴파일 된 코드는 기본 형식이 지정되어 있으면 정상적으로 실행됩니다. 비 프리미티브 유형의 연산자 함수를 호출하기 위해이를 확장 할 수 있습니다.
here을 참조하십시오.
내가 많이 사용하는 인터네트에서 도난당한 코드 조각이 있습니다. IL
기본 산술 연산자를 사용하여 찾습니다. 그것은 모두 Operation<T>
일반 클래스 내에서 이루어 지므로 필요한 작업을 대리인에게 할당하면됩니다. add = Operation<double>.Add
처럼.
다음과 같이 사용됩니다 붙여 넣기 빈의
public struct MyPoint
{
public readonly double x, y;
public MyPoint(double x, double y) { this.x=x; this.y=y; }
// User types must have defined operators
public static MyPoint operator+(MyPoint a, MyPoint b)
{
return new MyPoint(a.x+b.x, a.y+b.y);
}
}
class Program
{
// Sample generic method using Operation<T>
public static T DoubleIt<T>(T a)
{
Func<T, T, T> add=Operation<T>.Add;
return add(a, a);
}
// Example of using generic math
static void Main(string[] args)
{
var x=DoubleIt(1); //add integers, x=2
var y=DoubleIt(Math.PI); //add doubles, y=6.2831853071795862
MyPoint P=new MyPoint(x, y);
var Q=DoubleIt(P); //add user types, Q=(4.0,12.566370614359172)
var s=DoubleIt("ABC"); //concatenate strings, s="ABCABC"
}
}
Operation<T>
소스 코드 사의 씨 : 아래의 속성과 http://pastebin.com/nuqdeY8z
: 당신이
/* Copyright (C) 2007 The Trustees of Indiana University
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* Authors: Douglas Gregor
* Andrew Lumsdaine
*
* Url: http://www.osl.iu.edu/research/mpi.net/svn/
*
* This file provides the "Operations" class, which contains common
* reduction operations such as addition and multiplication for any
* type.
*
* This code was heavily influenced by Keith Farmer's
* Operator Overloading with Generics
* at http://www.codeproject.com/csharp/genericoperators.asp
*
* All MPI related code removed by ja72.
*/
당신의 예를 가지고 수행을 시도하는 경우 이것을 사용 하시겠습니까? 나는 어디에서나 유용하다고 생각할 수 없다. –
일반적인 "Sum"메서드는 간단한 예제입니다. T Sum (IEnumerable 시퀀스); // T가 '+'연산자 인 경우 –
blackwing
[+ 연산자를 구현하는 제네릭 정의] 가능한 복제본 (http://stackoverflow.com/questions/3598341/define-a-generic-that-implements-theoperator) – Timwi