1

如果我有一个对象,我只需要访问它的特定部分,我应该只传递那个特定部分还是应该传递整个对象?

就我而言,我正在使用 XNA 使用 C# 构建游戏,并且我需要访问“DrawLayer.cs”中 Camera 类的“边界”,该类绘制单个图层(假设由于视差而存在多个图层)游戏画面上。相机的“边界”作为以下属性存在:

    public Rectangle Bounds { get { return onScreenCamera.Bounds; } }

该游戏是一款多人游戏,有一个摄像头,可以根据玩家的动作在玩家之间跳转,因此“onScreenCamera”引用了当前需要使用的摄像头。此外,根据您的播放器类型,相机的功能会有所不同,因此我制作了一个接口 ICameraSetup.cs,我正在讨论的相机实现了该接口。这是 ICameraSetup 接口:

interface ICameraSetup
{
    Vector2 Position { get; }
    Rectangle Bounds { get; }

    void Update(GameTime pGameTime);
}

使用 DrawLayer.cs,我想像这样编写构造函数头(注意 Rectangle 是一个结构,这应该意味着它是一个值类型):

    public DrawLayer(ref Rectangle pBounds)

然后使用构造函数调用,就像这样:

    new DrawLayer(ref levelState.Camera.Bounds)

这只会将相机的边界传递给 DrawLayer.cs,但我似乎收到了这个错误:“属性 Game.Camera.ICameraSetup.Bounds 没有设置器。” 问题是,我不希望接口为 Bounds 声明一个 setter,因为唯一应该能够设置边界的类是 Camera 类,而 Bounds 的设置方式是通过上面提到的 camera 类中的私有变量,称为“onScreenCamera”。

但是,即使我将 Set 添加到 Bounds 属性,我仍然在 DrawLayer.cs 构造函数调用时收到此错误:“'ref' argument is not分类为变量。”

现在,我知道一种可行的解决方案是将整个相机传递到 DrawLayer.cs 并从那里使用边界,如下所示:

    public DrawLayer(ICameraSetup pCamera)

然后

    new DrawLayer(levelState.Camera)

然后使用Camera.Bounds,但这似乎没有必要,因为我需要的只是该类中的边界。

我可能遇到的另一个问题是我对传递引用的理解。我理解当您需要一个值类型引用以随时更新您传递给它的类之外的值所做的任何更改时,它很有用,但我也读到它是相反的:使用它在最初声明的位置之外更改值类型并使其保持不变。

那么我在将相机边界传递到 DrawLayer 时是否犯了一个错误?

4

2 回答 2

1

您忽略了第一个错误:

属性、索引器或动态成员访问不能作为 out 或 ref 参数传递。

此外,以这种方式通过引用传递参数意味着可以设置它,但不能设置,因为您没有为该Bounds属性定义公共设置器。所以,我们有两个问题。

我很困惑; 你为什么试图通过引用来传递它?您希望存储对此对象的引用,以便以后可以更改(仅供参考:您不能)?老实说,对我来说,这听起来像是一个糟糕的设计。这似乎不是性能问题,所以我建议调整您的设计。

当你遇到这样奇怪的事情并且变得笨重/不能很好地工作时,这通常意味着你手上有一个设计问题。不要试图通过引入更多设计问题来解决这个问题。

于 2012-07-11T00:38:46.230 回答
0

您不能通过引用传递属性。这是有道理的,因为属性不是变量——它们由编译器实现为 getter/setter 方法。

但是,您可以将 Bounds 属性更改为字段,或创建一个局部变量来保存 Bounds 的值,然后可以使用“ref”关键字传递它。

通过 'ref' 传递某些内容的主要原因是,如果您需要能够更改变量的任何部分,包括用新实例替换变量,并且您希望这会反映在调用代码中。

如果您只想访问 Bounds,请不要使用 'ref'。如果 Bounds 是一个结构,并且出于性能原因不想复制它,请考虑将 Bounds 设为一个类。

于 2012-07-11T01:01:20.630 回答