修复我的图形矢量类,二元运算符的参数之一必须是包含类型

时间:2014-11-27 02:06:26

标签: c# operator-overloading

http://codepaste.net/i87t39 我得到的错误是“二元运算符的一个参数必须是包含类型”

public class Vector3D<T>
{
    public T x; 
    public T y; 
    public T z;
    public Vector3D()
    {
    }
    public Vector3D(T a, T b, T c)
    {
        x = a; y = b; z = c;
    }
    /*public Vector3D(double a, double b, double c)
    {
        x = a; y = b; z = c;
    }*/
    public override string ToString()
    {
        //return base.ToString();
        return String.Format("({0} {1} {2})", x , y , z);
    }
    public Vector3D<double> operator+( Vector3D<double> right)
    {
        Vector3D<double> vd = new Vector3D<double>() { x = 0, y = 0, z = 0};
        vd.x = left.x + right.x;
        vd.y = left.y + right.y;
        vd.z = left.z + right.z;
        return vd;
    }
}

2 个答案:

答案 0 :(得分:0)

如果我复制链接中的代码:

public class Vector3D<T>
{
    public T x; 
    public T y; 
    public T z;
    public Vector3D()
    {
    }
    public Vector3D(T a, T b, T c)
    {
        x = a; y = b; z = c;
    }

    public override string ToString()
    {
        //return base.ToString();
        return String.Format("({0} {1} {2})", x , y , z);
    }
    public Vector3D<double> operator+( Vector3D<double> right)
    {
        Vector3D<double> vd = new Vector3D<double>() { x = 0, y = 0, z = 0};
        vd.x = left.x + right.x;
        vd.y = left.y + right.y;
        vd.z = left.z + right.z;
        return vd;
    }
}

您遇到的错误是在operator +中,因为包含类型为Exp<T>,而不是Exp<double>。你应该改变它。此方法中没有左边的定义!

你的方法应该是这样的:

    public static Vector3D<T> operator +(Vector3D<T> right)
    {

        Vector3D<T> vd = new Vector3D<T>();

        vd.x = right.x;
        vd.y = right.y;
        vd.z = right.z;
        return vd;
    }

答案 1 :(得分:0)

如果没有太多额外的工作,你将无法实现一个完全通用的通用Vector3D<T>类,其中包含数学运算符。您可以为通用类型提供约束,这些约束将允许T成为内置数字类型,同时为T提供数学运算符。

有多种方法可以解决这个问题,比如在通用类中使用特殊的类型(yuck!),需要T来实现一个接口(即在一个类型中包装一个普通的数字类型)实现接口),或使类型抽象,并要求专门的子类将运算符实现为命名方法(其中一个甚至可以依赖于接口,而其他直接基于数字类型的方法只是直接实现它们。)

例如:

abstract class Vector3D<T>
{
    public readonly T x;
    public readonly T y;
    public readonly T z;

    public Vector3D() { }
    public Vector3D(T x, T y, T z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public abstract Vector3D<T> Add(Vector3D<T> right);
}

class Vector3DDouble : Vector3D<double>
{
    public Vector3DDouble() { }
    public Vector3DDouble(double x, double y, double z)
        : base(x, y, z)
    { }

    public override Vector3D<double> Add(Vector3D<double> right)
    {
        return new Vector3DDouble(x + right.x, y + right.y, z + right.z);
    }
}

假设目前你已经以某种方式解决了这个问题,让我们来看看你的operator +超载。首先,您的代码甚至不会编译。您已经重载了一元+运算符,因为您只有一个参数right用于重载,但在方法体中,您假设第二个参数left是未声明的。

更明智的实现可能如下所示:

    public static Vector3D<T> operator+(Vector3D<T> left, Vector3D<T> right)
    {
        return left.Add(right);
    }

注意:我假设你已经通过要求实施者通过命名方法提供算术运算来解决算术问题,例如: {0}我的上述例子Add()。显然,这里的确切实现将取决于您如何处理使用T值进行数学运算的一般问题。