C#-使其只允许同一实例修改其属性/调用方法?
我正在用MonoGame框架制作一个游戏引擎。由于这是一个多人游戏,其他玩家需要知道其他玩家的某些信息,例如位置和速度,通常用于AI反应 我将为玩家操作实现Lua脚本。然而,我目前还没有想到一种方法,这样玩家就不能修改其他玩家的信息,比如位置和名字 例如,假设我在C#中有以下属性: 看起来不错,对吧?不完全是。假设我有一个函数返回最近的敌人,名为C#-使其只允许同一实例修改其属性/调用方法?,c#,.net,lua,monogame,C#,.net,Lua,Monogame,我正在用MonoGame框架制作一个游戏引擎。由于这是一个多人游戏,其他玩家需要知道其他玩家的某些信息,例如位置和速度,通常用于AI反应 我将为玩家操作实现Lua脚本。然而,我目前还没有想到一种方法,这样玩家就不能修改其他玩家的信息,比如位置和名字 例如,假设我在C#中有以下属性: 看起来不错,对吧?不完全是。假设我有一个函数返回最近的敌人,名为GetNearestEnemy(),它返回另一个玩家。因为Player类可以访问自己的属性,所以我可以用其他方法轻松地执行类似的操作: public v
GetNearestEnemy()
,它返回另一个玩家。因为Player类可以访问自己的属性,所以我可以用其他方法轻松地执行类似的操作:
public void DoStuff()
{
Player otherPlayer = GetNearestEnemy();
otherPlayer.Pos = new Vector2(34,151);
}
所以我想“也许我可以把实例作为参数传递。”
。。。并且总是把“这个”作为一个论点。然而,这也有同样的问题:我可以很容易地将GetNearestEnemy()
传递给该方法,并且我可以设置敌人的位置
这是我试图阻止的行为类型。是否有一种方法可以更好地:
:任何人都可以访问此public
:只有类型才能访问此private
:只有类型或该类型的后代才能访问此protected
:同一程序集中的任何类型都可以访问此内部
:同一程序集中的任何类型或后代都可以访问此internal protected
除此之外,您没有其他选择。因此,“只有相同的实例才能访问此”不作为访问修饰符存在。这不起作用。如果
Pos
是一个带有私有setter(按原样)的属性,那么他们可以更改它的唯一方法就是从otherPlayer
中调用公共方法。类似于otherPlayer.SetPos(新向量2(34151))
,其中SetPos()
是:
public void SetPos(Vector2 NewPos)
{ Pos = NewPos; }
如果这是酒店,您担心从其他地方设置:
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
Player otherPlayer=GetNearestEnemy();
otherPlayer.Pos=新矢量2(34151);// 发布的原始场景可以使用一个界面来处理,例如iperplayer,它只公开其他玩家应该看到的内容并隐藏其他属性(即其他属性不在iperplayer界面中。我不认为otherPlayer.Pos=new Vector2(34151)
应该可以工作-你真的测试过它吗?不,这里没有语言支持来处理你想要的东西。大概,既然你在编写这个类,你就要确保它不会做不应该做的事情。@MetaColon是的。因为DoStuff是Player中的一个方法,它可以访问Player类所做的一切。让GetNearestEnemy
返回源引用的克隆。这样,对克隆执行任何修改都将无法修改源引用。假设同一个程序员同时执行这两个类,这只是设计的一部分。如果有两个有竞争力的程序员,语言功能将无法阻止他们进行复制同一进程内的访问状态。但CLR具有一些隔离功能,如应用程序域(仅限完整的.NET Framework)。(请参阅.NET terrarium)因为DoStuff是Player中的一个方法,所以它可以访问Player类所做的一切。这就是我要说的。后者可以在类中完成,这是我不希望在该类的其他实例中发生的事情。好吧,这是一个令人不快的问题。经过一点思考,我想我应该做什么,而不是返回一个whol在这样的方法中,e player实例将返回一个结构,其中包含他们想要查看的值的只读副本。这样,脚本中的player对象可以从其他播放器获得他们想要的信息,但他们无法设置。感谢这些信息!您实际上可以通过闭包实现这一点,但您需要使用IDicti的一些变体例如expando对象。您没有类型系统支持,但可以使用闭包对实例级隐私进行建模。
public void SetPos(Vector2 NewPos)
{ Pos = NewPos; }
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