C# - make it所以只有同一个实例可以修改它的属性/调用方法?

时间:2017-05-20 18:56:18

标签: c# .net lua monogame

我正在使用MonoGame框架制作游戏引擎。由于这是一款多人游戏,其他玩家需要了解其他玩家的某些信息,例如位置和速度,通常用于AI反应。

我即将为玩家行动实施Lua脚本。但是,我现在无法想到一种方法,因此玩家无法修改其他玩家的信息,例如位置和名称。

例如,假设我在C#中有以下属性:

public Vector2 Pos { get { return pos; } private set { this.pos = value; } }
private Vector2 pos;

看起来不错吧?好吧不太好。假设我有一个函数返回最近的敌人GetNearestEnemy(),它返回另一个玩家。因为Player类可以访问它自己的属性,所以我可以在其他方法中轻松地做这样的事情:

public void DoStuff()
{
    Player otherPlayer = GetNearestEnemy();
    otherPlayer.Pos = new Vector2(34,151);
}

所以我认为“也许我可以将实例作为参数传递。”

public void SetPos(Player instance, Vector2 pos)
{
    if (instance != this)
        return;
    else
        this.pos = pos;
}

...并且总是将“this”作为参数传递。但是,这也有同样的问题:我可以轻松地将GetNearestEnemy()传递给方法,并且我可以设置敌人位置。

这是我试图阻止的行为类型。有没有办法优先:

  1. 获取调用方法的实例?
  2. 在不知道调用对象的情况下隐式设置参数?
  3. 或者还有其他方法可以接近它吗?

4 个答案:

答案 0 :(得分:2)

不幸的是没有。

没有语言支持你想要的东西。

让我具体说明你想要的是什么,以便你理解我所回答的内容。

你的问题基本上是这样的:鉴于我有一个对象的两个实例,并且我在这个对象中有一个私有setter的属性,是否有任何语言支持来确保实例#1无法更改实例#2的私人信息?

答案是否定的。

这将编译和"工作":

public class Test
{
    public void TestIt(Test t)
    {
        t.Value = 42;
    }

    public int Value
    {
        get;
        private set;
    }
}

...
var t1 = new Test();
var t2 = new Test();
t1.TestIt(t2); // will "happily" change t2.Value

基本上,责任在上,以确保如果您不希望这种情况发生,则不会发生这种情况。没有语言或运行时支持来阻止这种情况。

您可以使用的访问修饰符是:

  • public:任何人都可以访问此
  • private:只有该类型可以访问此
  • protected:只有类型或类型的后代才能访问此
  • internal:同一程序集中的任何类型 都可以访问此
  • internal protected:任何类型在同一个程序集 后代,都可以访问此

除此之外,您没有其他选择。所以"只有相同的实例才能访问这个"不存在作为访问修饰符。

答案 1 :(得分:0)

那不会奏效。如果Pos是具有私有设置器的属性(实际上),则可以通过从otherPlayer内调用公共方法来改变它。像otherPlayer.SetPos(new Vector2(34,151))这样的地方,其中SetPos()是:

public void SetPos(Vector2 NewPos)
    { Pos = NewPos; }

答案 2 :(得分:0)

如果这是属性而您担心从其他地方设置:

public Vector2 Pos { get { return pos; } private set { this.pos = value; } }
private Vector2 pos;

这不起作用。所以你不必担心:

Player otherPlayer = GetNearestEnemy();
otherPlayer.Pos = new Vector2(34,151); // <--- no this will not work

该属性只能在班级内设置。

答案 3 :(得分:0)

可以使用接口处理发布的原始场景,例如IPeerPlayer 只暴露其他玩家应该看到的内容并隐藏其他属性(即其他属性不会在 IPeerPlayer 界面中。