【问题标题】:Fix my Graphics vector class, One of the parameters of a binary operator must be the containing type修复我的 Graphics 矢量类,二元运算符的参数之一必须是包含类型
【发布时间】:2014-11-27 02:06:25
【问题描述】:

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;
    }
}

【问题讨论】:

    标签: c# operator-overloading


    【解决方案1】:

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

    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&lt;T&gt;,而不是 Exp&lt;double&gt;。你应该改变它。此方法中也没有 left 的定义!

    你的方法应该是这样的:

        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;
        }
    

    【讨论】:

    • 为什么不使用“this”?
    • @user366866 您正在尝试进行模板专业化(我认为这在 C++ 中是可能的),而这在 C# 中是不可能的。我认为这是因为 C# 泛型在编译期间没有被处理,并且更多是运行时的一个特性。它们是一些你可以在网上阅读的解决方法。
    【解决方案2】:

    如果不进行大量额外工作,您将无法实现一个完全通用的泛型 Vector3D&lt;T&gt; 类,并带有数学运算符。您可以为泛型类型提供任何约束,即允许T 成为内置数字类型,同时为T 提供数学运算符。

    有多种方法可以解决这个问题,例如在泛型类中对类型进行特殊封装(糟糕!),要求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);
        }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      • 2011-10-06
      • 1970-01-01
      • 1970-01-01
      • 2016-02-29
      • 1970-01-01
      • 2014-06-13
      相关资源
      最近更新 更多