2010-09-06 64 views
6

可能重复:
Define a generic that implements the + operator如何在C#泛型类型参数中强制支持一些运算符?

我最近工作的一个C#类库实现算法。关键是我希望库的用户能够选择算法应该使用的机器精度(单倍或双倍),并且我试图用泛型来实现。所以,举例来说:

Algorithm<double> a = new Algorithm<double>(); 
    /** Some initializations here */ 
    double result = a.Solve(); 

Algorithm<float> a = new Algorithm<float>(); 
    /** Some initializations here */ 
    float result = a.Solve(); 

因此,对于通用类的类型参数意味着是一个十进制数(因为在算法的代码,我需要用+,*, /, - ),但我不知道要对其施加哪种类型的约束。我曾想过与所有操作员建立一个界面,但不幸的是,这是不允许的。有任何想法吗?

否则,是否有可能在C#中获得类似于template specialization的东西?

谢谢

托马索

回答

7

你不能,基本上是这样。 CLR类型系统不支持这种约束。

我以前的博客是关于我们如何使用"static interfaces"来描述这样的约束,但我不知道有什么计划去做类似的事情。

你可能想看看MiscUtil generic operator support这将让你使用经营者 - 但你不得不使用的只是struct或类似的东西约束,这当然会允许像Guid事情,你不不想要。

+0

另一种可能性,而不是定义接口和类实现它们,你应该能够申报接口,并列出实现它们在接口声明的类。编译器应该照顾其余的 – devio 2010-09-07 14:42:15

+0

@devio:听起来像是一个有趣的变体。你能给一些参考吗? – tunnuz 2010-09-08 07:44:59

+0

@tunnuz没有“引用”,这是一个愿望,就像Jon的想法一样,并且应该在某人的下一个C#版本的愿望清单上;) – devio 2010-09-08 08:34:01

0

您可以使用一种变通方法:定义要询问服务

private static Add(float a, float b) 
{return a+b;} 
private static Add(double a, double b) 
{return a+b;} 
... 

和正确的创建委托每一个类型的方法在运行时:

MethodInfo addMethod=this.GetType().GetMethod("Add",BindingFlags.NotPublic|Static,null,new Type[2]{typeof(T),typeof(T)},null); 
Func<T,T,T> addFunction=(Func<T,T,T>)Delegate.CreateDelegate(typeof(Func<T,T,T>),addMethod); 
0

这通常是一个严重的问题y fugly hack,但您可以为数字类型创建一个通用的“包装器”类,以暴露您需要的操作,并防止使用不支持的值类型进行实例化。 char),然后指定算法的泛型类型参数必须是包装类。

我喜欢Floste除了代码重复各方面所构成的解决方法。你甚至可以简化它;指定私有方法重载,然后一个公共泛型方法,它将简单地调用私有方法,并且运行时将选择正确的方法(确保包含抛出NotImplementedException的全部方法)。