C# 从c中的结构继承的梦想#

C# 从c中的结构继承的梦想#,c#,inheritance,struct,xna,xna-4.0,C#,Inheritance,Struct,Xna,Xna 4.0,在那里,我正在用C#xna4.0制作一个2D游戏,再次遇到了我的一个小麻烦;矩形。对于那些使用基本碰撞的人来说,这几乎是必要的。对于几乎所有创建的游戏对象,都需要有一个矩形。然后我去改变X,检查碰撞,或者其他任何事情。在那里,我开始了一场永无止境的战斗objectName.Rectangle.which。为了解决这个问题,我当然给出了objectName属性/方法类,它们可以为我访问这些属性/方法 然后我敢做梦。我有宏伟的设计来创建一个基本的游戏对象类,所有可绘制的对象都将继承自该类,这将允许为

在那里,我正在用C#xna4.0制作一个2D游戏,再次遇到了我的一个小麻烦;矩形。对于那些使用基本碰撞的人来说,这几乎是必要的。对于几乎所有创建的游戏对象,都需要有一个矩形。然后我去改变X,检查碰撞,或者其他任何事情。在那里,我开始了一场永无止境的战斗
objectName.Rectangle.which
。为了解决这个问题,我当然给出了objectName属性/方法类,它们可以为我访问这些属性/方法

然后我敢做梦。我有宏伟的设计来创建一个基本的游戏对象类,所有可绘制的对象都将继承自该类,这将允许为人父母,精确的局部坐标(浮动),并保持纹理/精灵。为了完成这一点,我准备从矩形继承,使用它包含的所有方法和属性。见鬼,无论什么时候需要矩形,我都会懒得说objectName,而不是objectName.Rectangle

然后我意识到,没有机会。一开始我很沮丧,因为我的“哦,这么聪明”的想法被粉碎了。从那时起,我的完美的小类保存了一个矩形,并根据需要使用各种方法和属性访问它。我还借此机会从XNA DrawableGame组件继承了它。虽然从长远来看,这更实用,但每次我查看draw或update方法并看到对rectangle的调用时,我都会想,有没有希望做我想做的事情?是否有一些我可以做的聪明的工作?还是从一个长方形继承下来的东西真的不被我掌握

虽然使用XNA中提供的DrawableGameComponent类允许大多数与游戏对象相关的操作发生在class Update()方法内,但每次在类外我都需要引用矩形本身而不是矩形的属性,考虑到实际上我的对象在各个方面都是,把长方形放大。然后我再一次发现自己在问:


是否有任何方法可以从预定义结构继承,或给项目留下您是的印象(变通方法)?

这里有一个可能的变通方法(将其放入
MyClass
,您所说的类具有矩形属性):


例如,这将允许您将对象传递给一个方法,该方法需要一个
矩形
,并且可以工作。请注意,与真正的继承不同,存在的矩形不是您传入的
MyClass
的同一个实例,它只是一个由值构成的结构。

继承否,但您可以使用扩展方法向矩形对象添加许多“默认”功能。 比如说

  //(inside a static class)
  public static int GetSurface(this Rectangle rect){return rect.Width * rect.Height;}

  //calling
  Rectangle rect;
  var s = rect.GetSurface();

也就是说,我通常做的是封装所说的结构。将该类用作基本对象,并添加一个运算符,以便可以将其隐式转换为矩形。这样,它就可以传递给需要矩形的方法,而无需强制转换

    public class MyRect //class so you can inherit from it, but you could make your own struct as well
    {
        public int X { get; set; }
        public int Y { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
        public int Right { get { return X + Width; } }
        public int Bottom{ get { return Y + Height; } }

        public static implicit operator Rectangle(MyRect rect)
        {
            return new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
        }

        public static implicit operator MyRect(Rectangle rect)
        {
            return new MyRect { X = rect.X, Y = rect.Y, Width = rect.Width, Height = rect.Height };
        }

    }       
 }
现在,您可以手动或从现有的rect创建自己的rect:

  MyRect rect = ARectangleVar

您可以在期望矩形而不强制转换的遗留方法中使用它。值类型基本上与适用于类类型的继承样式不兼容,但是能够声明“派生结构”会有所帮助以这样一种方式,编译器将识别派生类型和原始类型之间的双向身份保持转换。派生结构必须有一个称为“Base”的字段(尽管C#编译器可以接受关键字
Base
作为替代项),其类型与派生结构的类型相同。名称与周围类型名称不匹配的“Base”的所有成员都将被视为封闭结构的成员

“派生结构”提供的主要功能(但目前还缺乏)是:

  • 无需添加额外的语法间接层即可访问包装结构的成员。例如,如果有一个类型为“Point”的实例“MyFancyPoint”,则可以说“MyFancyPoint.X+=5”,而不是“MyFancyPoint.Base.X+=5”。
  • 一次执行多个隐式或显式类型转换的能力。C#通常只允许从“X”到“Y”的转换,除非存在直接转换,部分原因是搜索所有可能的转换序列会很困难,部分原因是这样做通常会产生关于应该使用哪个转换序列的歧义。如果假设包装特定结构的所有类型都表示具有相互身份保持转换的“云”,则两个派生结构`XX:X`和`YY:Y`之间的转换可以明确地视为到`X`、然后是`Y`、然后是`YY`(如果存在`X`到`Y`的转换,则这是合法的)。
  • 将一种类型实例的ByRef视为另一种类型实例的ByRef,将一种类型字段的ByRef视为另一种类型中相应字段的ByRef的能力。 我不确定是否需要对运行时进行任何更改来支持这些特性中的任何一个,如果接受装箱派生类型的项只能作为相同的派生类型解除装箱;允许结构的盒装版本直接强制转换到可转换标识的派生结构的实例会有所帮助,但可能会增加复杂性。我不确定是否需要这样的行为才能使泛型工作。 不幸的是,我觉得很多负责做这种决定的人真的不喜欢价值类型。由于.net历史早期的一些设计决策(特别是缺少“const ref”参数和通过
    ref
    公开属性的方法),使结构以语义正确的方式工作可能是一个挑战,我认为一些实现者宁愿把结构的问题作为不改进.net对
      MyRect rect = ARectangleVar