帮助课堂上的数学操作数 (c#)
public class Racional<T>
{
private T nominator;
private T denominator;
public T Nominator
{
get { return nominator; }
set { nominator = value; }
}
public T Denominator
{
get { return denominator; }
set { denominator = value; }
}
public Racional(T nominator, T denominator)
{
this.nominator = nominator;
this.denominator = denominator;
}
public static Racional<int> operator *(Racional<int> a, Racional<int> b)
{
return ((int)(a.nominator + b.nominator, a.denominator + b.denominator));
}
public override string ToString()
{
return "(" + this.nominator + " " + this.denominator + ")";
}
}
我对这部分感兴趣:
public static Racional<int> operator *(Racional<int> a, Racional<int> b)
{
return ((int)(a.nominator + b.nominator, a.denominator + b.denominator));
}
出了什么问题:
二元运算符的参数之一必须是包含类型
我如何正常编码这部分以进行数学运算?
public class Racional<T>
{
private T nominator;
private T denominator;
public T Nominator
{
get { return nominator; }
set { nominator = value; }
}
public T Denominator
{
get { return denominator; }
set { denominator = value; }
}
public Racional(T nominator, T denominator)
{
this.nominator = nominator;
this.denominator = denominator;
}
public static Racional<int> operator *(Racional<int> a, Racional<int> b)
{
return ((int)(a.nominator + b.nominator, a.denominator + b.denominator));
}
public override string ToString()
{
return "(" + this.nominator + " " + this.denominator + ")";
}
}
I'm interested in this part :
public static Racional<int> operator *(Racional<int> a, Racional<int> b)
{
return ((int)(a.nominator + b.nominator, a.denominator + b.denominator));
}
What's wrong:
One of the parameters of a binary operator must be the containing type
How I can normaly code this part for mathematic operations?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
编译器错误解释了代码无法编译的原因。包含类型是泛型类型定义,从此类类型构造的泛型类型不被视为同一类型。
我有几个问题:
Rational
类型必须是通用的?有理数定义为可以表示为两个整数的商/分数(其中分母不是0
)的数字。为什么不使类型成为非泛型并在整个过程中简单地使用int
呢?或者您是否打算将该类型用于其他整数类型,例如long
和BigInteger
?在这种情况下,如果您想要某种代码共享机制,请考虑使用类似阿利斯塔德的建议。无论如何,您似乎希望能够“一般地”添加“可添加”类型的两个实例。不幸的是,目前没有任何方法可以在 C# 中表达“有合适的加法运算符”约束。
方法 #1: C# 4 中的一种解决方法是使用
dynamic
类型为您提供所需的“虚拟运算符”语义。如果该类型没有合适的加法运算符,该运算符将抛出异常。
方法#2:另一种(更有效)的方法是使用表达式树。
首先,创建并缓存一个委托,该委托可以通过编译适当的表达式来执行加法:(
如果类型没有合适的加法运算符,静态构造函数将抛出异常。)
然后在运算符中使用它:
The reason your code doesn't compile is explained by the compiler error. The containing type is a generic type definition, and a generic type constructed from such a type is not considered to be the same type.
I have a few questions:
Rational
type be generic? A rational number is defined as a number that can be expressed as the quotient / fraction of two integers (where the denominator is not0
). Why not make the type non-generic and simply useint
throughout? Or do you intend that the type be used for other integral types such aslong
andBigInteger
? In that case, consider using something like Aliostad's suggestion if you want some code-sharing mechanism.In any case, you appear to want to be able to 'generically' add two instances of an 'addable' type. Unfortunately, there currently isn't any way to express a 'has a suitable addition operator' constraint in C#.
Method #1: One workaround for this in C# 4 is to use the
dynamic
type to give you the desired "virtual operator" semantics.The operator will throw if the type doesn't have a suitable addition operator.
Method #2: Another (more efficient) way is to use expression-trees.
First, create and cache a delegate that can perform the addition by compiling the appropriate expression:
(The static constructor will throw if the type doesn't have a suitable addition operator.)
Then employ it in the operator:
这里的问题是您正在类
Racional
中为Racional
定义一个运算符。这是不可能的。 类型不相同,只能为Racional
定义运算符。泛型无法表达运算符的泛化,因为它们仅为特定类型定义解决方案是创建一个类并继承自
Racional
:The issue here is you are defining an operator for
Racional<int>
in the classRacional<T>
. This is not possible. The types are not the same, you can only define operator forRacional<T>
.Generics cannot express generalization of operators since they are defined only for a certain types. Solution is to create a class and inherit from
Racional<int>
:要解决您的问题,您需要提供从
T
到定义了operator+
的某种类型的转换函数,反之亦然。假设 Int64 在大多数情况下足够大,可以这样做:当然,这有一个缺点,您必须在程序启动时的某个地方提供这些转换器的初始化,应该如下所示:
在真实的程序中,您可能知道要使用哪些可能的
T
替代品。因此,可以在静态构造函数中提供这 3 或 4 个调用,如下所示:在大多数情况下应该足够了。请注意,此转换器初始化对所有 3 种类型重复 3 次,从而多次重新初始化转换函数。实际上这不会造成任何麻烦。
To solve your issue, you need to provide conversion functions from
T
to some type whereoperator+
is defined and vice versa. AssumingInt64
is big enough in most cases, this can be done this way:Of course, this has the drawback that you must provide the initialization of those converters somewhere at the program start, should look like this:
In a real program, you may know which possible replacements for
T
you are going to use. So one can provide those 3 or 4 calls in a static constructor like this:should be sufficient in most cases. Note that this converter initialization is repeated for all 3 types 3 times again, re-initializing the conversion functions multiple times again. In practice this should not make any trouble.