繁体   English   中英

C# 方法参数和子类类型

[英]C# Method arguments and Subclass Types

我开始学习 C#,但我对某些事情感到困惑。 假设我有一个类和 2 个子类。 我在父类中有一个名为 Add() 的方法。 但是当我将此方法与子类一起使用时,由于该方法要求的是“Toople”而不是“Vector”或“Point”,它给了我一个错误。 我该如何解决这个问题? 有没有办法允许将子类插入到方法中,还是应该为每个不同的子类创建新方法? 非常感谢。

using System;
namespace RayTracerChallange
{
    public class Toople
    {
        public float x, y, z, w;

        public Toople(float X, float Y, float Z, float W)
        {
            x = X;
            y = Y;
            z = Z;
            w = W;

        }
        public Toople Add(Toople Toop)
        {
            return new Toople(this.x + Toop.x, this.y + Toop.y, this.z + Toop.z, this.w + Toop.w);
        }

  public class Point : Toople
  {
      Point(float X, float Y, float Z) : base(X, Y, Z, 1)
      {
          this.x = X;
          this.y = Y;
          this.z = Z;
      }
  }

  public class Vector : Toople
  {
      Vector(float X, float Y, float Z) : base(X, Y, Z, 0)
      {
          this.x = X;
          this.y = Y;
          this.z = Z;
      }
  }

最接近这里的方法是使Toople通用和抽象,可能是通过执行以下操作:

using System;
namespace RayTracerChallange
{
    public abstract class ToopleBase<T> where T : ToopleBase<T>
    {
        public float x, y, z, w;

        protected Toople(float X, float Y, float Z, float W)
        {
            x = X;
            y = Y;
            z = Z;
            w = W;

        }
        protected abstract T MakeT(float X, float Y, float Z, float W);

        public T Add(Toople Toop)
        {
            return makeT(this.x + Toop.x, this.y + Toop.y, this.z + Toop.z, this.w + Toop.w);
        }
  }

  public class Toople : ToopleBase<Toople>
  {
      Toople(float X, float Y, float Z, float W) : base(X, Y, Z, W)
      {
      }

      Toople MakeT(float X, float Y, float Z, float W)
      {
          return new Toople(X, Y, Z, W);
      }
  }

  public class Point : ToopleBase<Point>
  {
      Point(float X, float Y, float Z) : base(X, Y, Z, 1)
      {
      }

      protected override Point MakeT(float X, float Y, float Z, float W)
      {
          return new Point(X, Y, Z);
      }
  }

  public class Vector : ToopleBase<Vector>
  {
      Vector(float X, float Y, float Z) : base(X, Y, Z, 0)
      {
      }

      protected override Point MakeT(float X, float Y, float Z, float W)
      {
          return new Vector(X, Y, Z);
      }
  }

需要注意的几点:

  • 我不确定您为什么要这样做,如果您遵循 Liskov 替换原则,那么只需返回基类Toople就足够了。 (也就是说,应用程序的其余部分应该能够期望任何子类与其基类的行为方式相同,甚至不应该知道子类存在。)
  • 子类的构造函数不需要在父类中设置字段,因为父类已经这样做了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM