数学和泛型 [英] Mathematics and generics

查看:103
本文介绍了数学和泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我需要实现,除其他外,这两种特定类型: ComplexNumber< T> 矩阵和LT; T> T 可以是下列之一:的有理数,一个的实数或整数

Ok, I need to implement, among others, these two particular types: ComplexNumber<T> and Matrix<T>. T can be one of the following: a rational number, a real number or integers.

在System命名空间我有实数(小数),整数( INT A很好的代表性或)。 Numerics.ComplexNumber 不削减内部监守 RealPart ImaginaryPart 双击,我买不起,在这种特殊情况下,这种类型的代表性误差。

In the System namespace I have a good representation for real numbers (decimal), integer numbers (int or long). Numerics.ComplexNumber does not cut it becuase internally RealPart and ImaginaryPart are double and I can't afford, in this particular case, the representation error of this type.

现在,probem当然,有没有办法约束泛型参数 T 数学有效的类型。也就是说,我不能做到以下几点:

Now, the probem is of course that there is no way to constraint the generic parameter T to mathematical "valid" types. That is, I can't do the following:

public struct ComplexNumber<T>
{
     readonly T realPart;
     readonly T imaginaryPart;

     public static ComplexNumber<T> Add(ComplexNumber<T> left, ComplexNumber<T> right)
     {
         return new ComplexNumber<T>(left.realPart + right.realPart, left.imaginaryPart + right.imaginaryPart); //Compile time error. No operator defined for T
     }
}



所以我需要一个解决办法。尽管性能不是目的本身,我想代码的工作还算不错,但首先,我想这是最优雅的解决方案成为可能。现在,我已经想出了两种可能性:

So I need a workaround. Although performance is not a goal in itself, I'd like the code to work reasonably well, but above all, I'd like it to be the most elegant solution possible. Right now I've come up with two possibilities:

A 数字抽象基类类似于:

A Numeric abstract base class similar to:

public abstract class Numeric
{
    protected abstract Numeric _Add(Numeric right);
    protected abstract Numeric _Subtract(Numeric right);

    public static Numeric Add(Numeric left, Numeric right) { return _Add(this, right); }
    public static Numeric Subtract(Numeric left, Numeric right) { return _Subtract(this, right);
}

现在我可以这样做:

public sealed class RationalNumber: Numeric
{
     readonly long numerator, denominator;

     protected override Numeric _Add(Numeric right) { //Rational addition implementation }
}

然后矩阵和LT;有理数> 矩阵和LT; ComplexNumber方式> 将工作

另一个选择是通过一个接口来做到这一点:

The other option is to do it through an interface:

public INumeric
{
     INumeric Add(INumeric right);
     INumeric Subtract(INumeric right);
}

public struct RationalNumber: INumeric
{
     readonly long numerator, denominator;

     public static RationalNumber Add(RationalNumber left, RationalNumber right) { //Rationa add implementation }
     INumeric INumeric.Add(INumeric right) //explicit to not clog up the type and to convey the idea of a framework mechanism.
     {
          if (!(right is RationalNumber))
              throw new ArgumentException();

          Add(this, (RationalNumber)right);
     }



接口选项,让我实现有理数为结构至极是,恕我直言,如何与数字类型的框架中实现更加一致。另外,类型本身是相当轻巧,通常会有短暂的一生。在数字基类的解决方案似乎是一大堆更多重量级的,但我不是一个真正的专家准确量化一个比其他的优势,当谈到:

The interface option lets me implement RationalNumber as a struct wich is, IMHO, more consistent with how numeric types are implemented in the framework. Also the types themselves are pretty lightweight and will typically have short lives. The Numeric base class solution seems like a whole lot more heavyweight, but I'm not really an expert to exactly quantify the advantages of one over the other when it comes to:


  • 代码qualitiy和未来的可扩展性和维护

  • 性能和内存消耗(好奇心比什么都重要)

  • 一个更好的解决方案?

如果任何人都可以揭示了一点点,我。会感激它

If anyone can shed a little bit of light, I'd appreciate it.

推荐答案

您可以使用扩展的方法来解决这个问题:

You can use extensions method to solve this problem:

public struct ComplexNumber<T>
{
    private readonly T _realPart;
    private readonly T _imaginaryPart;

    public ComplexNumber(T realPart, T imaginaryPart)
    {
        _realPart = realPart;
        _imaginaryPart = imaginaryPart;
    }

    public T RealPart
    {
        get
        {
            return _realPart;
        }
    }

    public T ImaginaryPart
    {
        get
        {
            return _imaginaryPart;
        }
    }

    public override string ToString()
    {
        return string.Format("({0}, {1})", RealPart, ImaginaryPart);
    }
}

public static class ComplexNumberExtensions
{
    public static ComplexNumber<int> Add(this ComplexNumber<int> self, ComplexNumber<int> other)
    {
        return new ComplexNumber<int>(self.RealPart + other.RealPart, self.ImaginaryPart + other.ImaginaryPart);
    }

    public static ComplexNumber<double> Add(this ComplexNumber<double> self, ComplexNumber<double> other)
    {
        return new ComplexNumber<double>(self.RealPart + other.RealPart, self.ImaginaryPart + other.ImaginaryPart);
    }

    // Add similar extension methods for each numeric type you need
}

使用这样的:

var first = new ComplexNumber<int>(1, 2);
var second = new ComplexNumber<int>(3, 4);
var result = first.Add(second);
Console.WriteLine(result);

这篇关于数学和泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆