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

在那里,我正在用C#XNA 4.0制作一款2D游戏,并且再次遇到我的一个小小的烦恼; 矩形 。 对于那些使用基本碰撞的人来说,这几乎是必需的。 几乎所有创建的游戏对象都需要有一个矩形。 然后我去改变X,检查碰撞或其他任何事情。 在那里,我开始了无尽的争夺objectName.Rectangle.Whatever 。 为了解决这个问题,我当然要为我提供访问这些对象的objectName属性/方法的类。

然后我敢做梦。 我有伟大的设计,使一个基本的游戏对象类,所有drawable将继承,这将允许父母,精确的本地坐标(浮游物),并保持纹理/ spritebatch。 为了完成这个任务,我准备从Rectangle继承,使用它所拥有的所有方法和属性。 哎呀,无论什么时候需要一个Rectangle,我可能会懒惰地说objectName,而不是objectName.Rectangle。

然后我意识到,不是一个机会。 我开始沮丧,因为我那聪明的主意被砸碎了。 从那时起,我完美的小班拥有一个矩形,并根据需要使用各种方法和属性访问它。 我也抓住了从XNA DrawableGameComponent继承的机会。 从长远来看,这更加实用,每次我查看绘制或更新方法,并看到我经常想知道的矩形调用时,有没有希望做我想做的事情? 我可以做些巧妙的工作吗? 或者是从我的掌握中真正密封的矩形继承?

虽然使用XNA中提供的DrawableGameComponent类允许大多数与游戏对象相关的动作发生在类Update()方法内部,但每次我不需要引用Rectangle的属性,而是引用Rectangle本身时,考虑到事实上,我的目标实际上在每个方面都是强化的矩形。 然后我再次发现自己在问:

有没有办法从预定义的结构继承,或给项目留下印象(解决方法)?


继承否,但可以使用扩展方法为Rectangle对象添加许多“默认”功能。 例如

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

    }       
 }

现在您可以手动创建自己的矩形或从现有矩形创建矩形:

  MyRect rect = ARectangleVar

你可以在传统的方法中使用它,期望一个矩形而不需要投射


这里有一个可能的解决方法(把它放在MyClass ,你说的那个类有一个Rectangle属性):

public static implicit operator Rectangle(MyClass obj)
{
    return obj.Rectangle;
}

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


值类型基本上与适用于类类型的继承类型不兼容,但能够以这样一种方式声明“派生结构”将会有所帮助:编译器会识别导出之间的双向同一保持转换类型和原件。 派生结构将被要求只有一个字段,名为“Base”(虽然C#编译器可以接受关键字base作为替代),其类型是被派生的结构的类型。 所有名称与周围类型不匹配的“基地”成员将被视为封闭结构的成员。

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

  • 访问封装结构成员的能力,而不必添加额外的语法间接层。 例如,如果有一个实例`MyFancyPoint`的类型偏离了`Point`,可以说`MyFancyPoint.X + = 5`而不是`MyFancyPoint.Base.X + = 5`。
  • 一次执行多个隐式或显式类型转换的能力。 除了存在直接转换之外,C#一般只允许从`X`转换为`Y`,部分原因是因为搜索所有可能的转换序列会很困难,部分原因是因为这样做通常会产生含糊不清的转换序列应该被雇用。 如果所有包装特定结构的类型被假定为表示具有保留转换的保护转换的“云”,则两个派生结构“XX:X”和“YY:Y”之间的转换可以被明确地视为转换为“X” ,然后是'Y',然后是'YY'(如果'X'到'Y'转换存在,这将是合法的)。
  • 能够将ByRef视为一个类型的实例作为另一个类型的实例的ByRef,而将一个ByRef视为另一个类型的字段的ByRef被视为ByRef。

    我不确定是否需要对运行时所做的任何更改来支持这些功能,如果您接受将盒装派生类型的项目仅作为相同的派生类型进行拆箱; 允许将盒装版本的结构直接转换为可转换为身份标识的实例的实例会很有帮助,但可能会增加复杂性。 我不确定是否需要这种行为才能使仿制药发挥作用。 不幸的是,我感觉许多负责做出这种决定的人真的不喜欢价值类型。 由于一些设计决定在.net中的历史(尤其是缺乏“常量参考”参数和揭露被性质的手段早期的ref ),使得结构在语义正确的方式工作是一个挑战,我觉得有些实施者宁愿使用结构上的问题作为不改善.net对它们的处理的借口,而不是增加能够解决问题的功能。

    链接地址: http://www.djcxy.com/p/95519.html

    上一篇: The dream to inherit from a struct in c#

    下一篇: How to share derived fields between instances of the same class?