C#XNA在构造函数中通过引用类传递

时间:2012-06-13 09:18:08

标签: c# xna pass-by-reference

我正在XNA制作矢量图形游戏。我设计了一个Line类来围绕中心点旋转,以帮助绘制特定的形状。为了保持单一的真实点,有没有办法将形状中心的引用传递给我创建的所有线,这样更新中心的位置也会更新线的位置?我觉得这样的事情会奏效:

class Line
{
    private Vector2 start;
    private double length;
    private double angle;

    public Line(ref Vector2 start, double length, double angle){
        this.start = start;
        this.length = length;
        this.angle = angle;
    }
}




class Obj
{
    private Vector2 center;
    private Line[] lines;
    public Obj(){
        center = new Vector2(50,50);
        lines = new Lines[5];
        for (int i = 0; i < 5; i++){
            lines[i] = new Line(ref center,30, (i/5 * 2 * Math.PI));

        }

    }
}

但移动中心时线条不会更新。我做错了什么?

2 个答案:

答案 0 :(得分:4)

虽然通过引用struct正确传递了Line,但是在内部分配它时:

public Line(ref Vector2 start, double length, double angle){
    this.start = start;
}

您实际上正在使用struct副本

如果您发现自己需要struct的引用类型语义而不是将其传递给单个方法,那么您可能需要使用class重新考虑。

您可以在类中重新实现该类型,也可以将Vector2包装在类中并使用它:

class Vector2Class
{
    public Vector2 Centre;

    public Vector2Class(Vector2 inner)
    {
        Centre = inner;
    }
}

class Line
{
    private Vector2Class _centre;

    public Line(Vector2Class centre)
    {
        _centre = centre;    
    }
}

请注意,您仍在使用副本,但如果您共享该类,则您将全部使用相同的副本。

就个人而言,我会避免包装并创建自己的类来代表“center”。这得到了struct类型应该是不可变的基本上被接受的观点的支持,但是您似乎需要改变值以保持表示真实。

class CentreVector<T>
{
    public <T> X { get; set; }
    public <T> Y { get; set; }
}

这只允许您共享数据,它实际上并不通知中心已更改的行。为此你需要某种事件。

答案 1 :(得分:2)

使用替代解决方案进行编辑

你遇到的问题是因为Vector2是一个值类型,你正确地在你的方法参数中通过ref传递它,然后用赋值来制作它的本地副本。

我不完全确定你是否可以按照你想的方式维护指向Vector2的指针,但你可以创建自己的Vector2类作为引用类型。

class ObjectVector2
{
    public float X { get;set; }
    public float Y { get; set; }
}

我想建议一种稍微不同的方法,通过保持对行所属的obj的引用来实现相同的结果。

class Line
{

    private Vector2 Center { get { return parent.center; } }
    private double length;
    private double angle;
    Obj parent;

    public Line(Obj parent, double length, double angle)
    {
       this.parent = parent;
       this.length = length;
       this.angle = angle;
    }
}

class Obj
{
    public Vector2 center;
    private Line[] lines;
    public Obj()
    {
        center = new Vector2(50, 50);
        lines = new Lines[5];
        for (int i = 0; i < 5; i++)
        {
           // passing the reference to this Obj in the line constructor.
           lines[i] = new Line(this, 30, (i / 5 * 2 * Math.PI));
        }

    }
}