是否有一个“实数”types的C#通用约束?

可能重复:
C#通用约束只有整数

映入眼帘!

我正在尝试在C#中设置一个笛卡尔坐标系,但是我不想将自己的坐标值限制为任何一种数字types。 有时他们可能是整数,有时他们可能是有理数,取决于上下文。

这尖叫“generics类”给我,但我不知道如何将types收敛到积分和浮点。 我似乎无法find一个涵盖任何实数概念的类。

public class Point<T> where T : [SomeClassThatIncludesBothIntsandFloats?] { T myX, myY; public Point(T x, T y) { myX = x; myY = y; } } Point<int> pInt = new Point<int>(5, -10); Point<float> pFloat = new Point<float>(3.14159, -0.2357); 

如果我想要这样的自由度,当我在课堂上进行计算时,是否会select“type(T)”的噩梦,除去布尔,string,对象等? 或者更糟糕的是,我是否select为每个想要使用的数字types创build一个类,每个类都使用相同的内部math公式?

任何帮助,将不胜感激。 谢谢!

你不能定义这样的约束,但你可以在运行时检查types。 这不会帮助你做计算。

如果你想做计算,这样的事情将是一个select:

 class Calculations<T, S> where S: Calculator<T>, new() { Calculator<T> _calculator = new S(); public T Square(T a) { return _calculator.Multiply(a, a); } } abstract class Calculator<T> { public abstract T Multiply(T a, T b); } class IntCalculator : Calculator<int> { public override int Multiply(int a, int b) { return a * b; } } 

同样,定义一个FloatCalculator和你需要的任何操作。 它不是特别快,但比C#4.0 dynamic构造更快。

 var calc = new Calculations<int, IntCalculator>(); var result = calc.Square(10); 

副作用是,如果传递给它的types具有匹配的Calculator<T>实现,则只能实例化Calculator ,因此不必执行运行时types检查。

基本上这就是Hejlsberg在这次采访中提到的问题。 我个人还是希望看到某种基types:)

这是一个很常见的问题。 如果你使用.NET 3.5,在MiscUtil中有很多支持,通过Operator类,它支持内置types和任何自定义types的运营商(包括“提升”的运营商)。 特别是,这允许与generics一起使用,例如:

 public static T Sum<T>(this IEnumerable<T> source) { T sum = Operator<T>.Zero; foreach (T value in source) { if (value != null) { sum = Operator.Add(sum, value); } } return sum; } 

或者换另一个例子; Complex<T>

这是一个已知的问题,因为没有一个算术类来自同一个类。 所以你不能限制它。

你唯一能做的就是

 where T : struct 

但那不完全是你想要的。

这是一个特定问题的链接。

像int,double,decimal这样的算术types应该实现IArithmetic <T>

实际上,你可以做到这一点,虽然解决方法是繁琐的设置,可能会让开发人员不知道为什么这样做。 (所以如果你select这样做的话,它会很好地!)…

创build两个名为say,MyInt和MyDecimal的结构,它们作为CTS Int32的外观,以及Decimal核心types(它们包含相应types的内部字段)。每个结构都应该有一个采用Core CTStypes实例的ctor作为input参数..

使每个实现一个名为INumeric的空接口

然后,在你的generics方法中,根据这个接口进行约束。 不利的一点是,在任何想要使用这些方法的地方,都必须构build适当的自定义types的实例,而不是Core CTStypes,并将自定义types传递给方法。

注意:对自定义结构进行编码以正确模拟核心CTStypes的所有行为是单调乏味的部分…您必须实现多个内置的CLR接口(IComparable等),并重载所有算术和布尔运算符。 ..

你可以靠近几个实施

 public class Point<T> where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T> { } 

签名也符合DateTime 。 我不确定您是否能够从框架中指定更多的types。 无论如何,这只能解决部分问题。 要进行基本的数字操作,您将不得不包装数字types,并使用generics方法而不是标准操作符。 看到这个问题的几个选项。

这可能会有所帮助。 你必须使用一个通用的类来实现你想要的。

C#当前不允许在值types上使用types约束。 我不久前问了一个相关的问题。

C#中的枚举types约束

这不适合分开实施IPoint的课程吗?

就像是:

 public interface IPoint<T> { TX { get; set; } TY { get; set; } } public class IntegerPoint : IPoint<int> { public int X { get; set; } public int Y { get; set; } } 

因为计算将不得不在每个实施方面有所不同吗?

担#