首页 > 解决方案 > 在 C# 的抽象类中重载运算符(如 +、-、*、/)

问题描述

我正在尝试将类 Vector 实现为抽象类,并继承 Vector2D 和 vector3D 之类的东西。但是,我遇到了覆盖运算符的问题,因为它们要求返回一个静态对象引用,而我不能创建一个,因为我不允许在那里调用抽象类的构造函数。

这是我想出的覆盖:

    public static Vector operator +(Vector v1, Vector v2)
    {
        if (v1.Dimension != v2.Dimension)
        {
            throw new Exception("Vector Dimensions Must Be Equal");
        }
        else
        {
            double[] newMatrix = new double[v1.Dimension]; //the matrix for the new (resulting) vector 
            for (int i = 0; i < v1.Dimension; i++)
            {
                newMatrix[i] = v1.Matrix[i] + v2.Matrix[i];
            }
            return new Vector(newMatrix);
            //the abstract class has a constructor that takes a matrix
            //and constructs a vector based on it, but it can't be called here
        }
    }

我尝试使用矩阵构造函数并生成一个新的空实例(我有这些构造函数中的任何一个)。两者都归结为“无法实例化抽象类”错误。

我知道我可以在从 Vector 派生的每个类中实现操作,但我希望有一些解决方法/技术/设计模式可以以更优雅的方式解决问题,但我似乎没有找到那里有任何关于在抽象类中重写运算符的文章(也许这种方法没有意义......?)。无论如何,非常感谢任何帮助。如果需要,这是整个班级:

using System;
using System.Text;

namespace PhysicsProblems
{
    public abstract class Vector
    {
        private static int IdCounter;

        protected readonly int ID;

        protected double[] Matrix;

        protected int Dimension
        {
            get
            {
                return Matrix.Length;
            }
        }

        public double Magnitude
        {
            get
            {
                double sum = 0;
                foreach (var value in Matrix)
                {
                    sum += value * value;
                }
                return Math.Sqrt(sum);
            }
        }

        public Vector(int dimension)
        {
            ID = IdCounter++;
            for (int i = 0; i < dimesion; i++)
            {
                Matrix[i] = 0;
            }
        }

        public Vector(double[] matrix)
        {
            ID = IdCounter++;
            matrix.CopyTo(Matrix, 0);
        }

        public static Vector operator +(Vector v1)
        {
            return v1;//to fix
        }
        public static Vector operator -(Vector v1)
        {
            for (int i = 0; i < v1.Matrix.Length; i++)
            {
                v1.Matrix[i] = -v1.Matrix[i];
            }
            return v1;//to fix
        }
        public static Vector operator +(Vector v1, Vector v2)
        {
            if (v1.Dimension != v2.Dimension)
            {
                throw new Exception("Vector Dimensions Must Be Equal");
            }
            else
            {
                double[] newMatrix = new double[v1.Dimension]; //the matrix for the new (resulting) vector 
                for (int i = 0; i < v1.Dimension; i++)
                {
                    newMatrix[i] = v1.Matrix[i] + v2.Matrix[i];
                }
                return new Vector(newMatrix);
                //the abstract class has a constructor that takes a matrix
                //and constructs a vector based on it, but it can't be called here
            }
        }

        public bool Equals(Vector vector)
        {
            if (vector.Dimension != Dimension) return false;

            bool check = true;
            for (int i = 0; i < Matrix.Length; i++)
            {
                if (vector.Matrix[i] != Matrix[i]) check = false;
            }
            return check;
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as Vector);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int hash = 19;
                hash = (hash * 486187739) + ID.GetHashCode();
                hash = (hash * 486187739) + Dimension.GetHashCode();
                return hash;
            }
        }

        public override string ToString()
        {
            if (Dimension < 4)
            {
                var stringBuilder = new StringBuilder();
                for (int i = 0; i < Dimension; i++)
                {
                    stringBuilder
                        .Append(Constants.AxisLetters[i])
                        .Append(": ")
                        .Append(Matrix[i]);
                    if (i != Dimension - 1) stringBuilder.Append(", ");
                }
                return stringBuilder.ToString();
            }
            else
            {
                throw new NotImplementedException();
            }
        }
    }
}

以及继承类 Vector2D:

using System;
using System.Text;

namespace PhysicsProblems
{
    public class Vector2D : Vector
    {

        public double X
        {
            get { return Matrix[0]; }
            set { Matrix[0] = value; }
        }

        public double Y
        {
            get { return Matrix[1]; }
            set { Matrix[1] = value; }
        }

        public Vector2D(int dimension) : base(dimension)
        { }
        public Vector2D(double[] matrix) : base(matrix)
        { }
    }
}

我认为重要的一点免责声明:我对 OOP 还算不错,并且有一些经验,但是,我在一两周前开始使用 C#。因此,菜鸟失误是意料之中的

标签: c#oopoverridingabstract-classbinary-operators

解决方案


推荐阅读