.NET 제네릭의 오버로드된 연산자 제약 조건에 대한 솔루션
-
02-07-2019 - |
문제
예를 들어 빼기 연산자와 같이 연산자가 오버로드된 유형만 허용하는 일반 메서드를 갖고 싶다면 어떻게 해야 합니까?인터페이스를 제약 조건으로 사용해 보았지만 인터페이스에는 연산자 오버로딩이 있을 수 없습니다.
이를 달성하는 가장 좋은 방법은 무엇입니까?
해결책
즉각적인 대답은 없습니다. 연산자는 정적이며 제약 조건으로 표현할 수 없으며 기존 원시는 특정 인터페이스를 구현하지 않습니다 (Icompayble [incompayble [u003CT> ] 이는 더 큰 / 덜 에뮬레이션하는 데 사용할 수 있습니다).
하지만; 당신이 그것이 작동하기를 원한다면 .NET 3.5에는 몇 가지 옵션이 있습니다 ...
나는 도서관을 모았다 여기 이를 통해 다음과 같은 제네릭을 가진 운영자에 효율적이고 간단한 액세스를 허용합니다.
T result = Operator.Add(first, second); // implicit <T>; here
의 일부로 다운로드 할 수 있습니다 오해
또한 C# 4.0에서는이를 통해 가능해집니다. 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>;
지저분한 모든 방법을 통해.
다른 팁
저는 IL이 실제로 이 문제를 꽤 잘 처리할 수 있다는 것을 알았습니다.전.
ldarg.0
ldarg.1
add
ret
일반 메소드로 컴파일하면 기본 유형이 지정되는 한 코드는 정상적으로 실행됩니다.기본이 아닌 유형에서 연산자 함수를 호출하도록 이를 확장하는 것이 가능할 수 있습니다.
보다 여기.
내가 이것을 위해 많은 것을 사용하는 국민들로부터 도난당한 코드가 있습니다. 사용을 찾거나 빌드합니다 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.
*/