C# - 让它只有同一个实例可以修改它的 properties/call 方法?
C# - make it so only the same instance can modify its properties/call methods?
我正在使用 MonoGame 框架制作游戏引擎。由于这是一款多人游戏,其他玩家需要了解其他玩家的某些信息,例如位置和速度,通常用于 AI 反应。
我即将实施 Lua 玩家操作脚本。但是,我目前想不出有什么办法让玩家无法修改其他玩家的信息,例如位置和姓名。
例如,假设我在 C# 中有以下 属性:
public Vector2 Pos { get { return pos; } private set { this.pos = value; } }
private Vector2 pos;
看起来不错吧?好吧,不完全是。假设我有一个函数,returns 最近的敌人叫 GetNearestEnemy()
,returns 另一个玩家。因为 Player class 可以访问它自己的属性,所以我可以用其他方法轻松地做这样的事情:
public void DoStuff()
{
Player otherPlayer = GetNearestEnemy();
otherPlayer.Pos = new Vector2(34,151);
}
所以我认为"maybe I could just pass the instance as a parameter."
public void SetPos(Player instance, Vector2 pos)
{
if (instance != this)
return;
else
this.pos = pos;
}
... 并始终将 "this" 作为参数传递。然而,这也有同样的问题:我可以很容易地将 GetNearestEnemy()
传递给该方法,并且我能够设置敌人的位置。
这是我试图阻止的行为类型。有没有办法最好:
- 获取调用方法的实例?
- 在调用对象不知情的情况下隐式设置参数?
或者有其他我没有看到的方法吗?
很遗憾没有。
没有您想要的语言支持。
让我具体说明您想要什么,以便您理解我的回答。
你的问题基本上是这样的:鉴于我有一个对象的 两个 个实例,并且我在这个对象中有一个私有 setter 的属性,是否有是否支持确保实例 #1 无法更改实例 #2 的私有信息的任何语言?
答案是否定的
这将编译并且 "work":
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
:任何类型在同一个程序集或的后代,都可以访问这个
除此之外,您别无选择。所以 "only the same instance can access this" 不作为访问修饰符存在。
那不行。如果 Pos
是一个带有私有 setter 的 属性(实际上),那么他们可以更改它的唯一方法是从 [=12= 中调用 public 方法].类似于 otherPlayer.SetPos(new Vector2(34,151))
,其中 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
属性 只能在 class 中设置。
发布的原始场景可以使用接口来处理,例如IPeerPlayer 只公开其他玩家应该看到的内容并隐藏其他属性(即其他属性不会出现在 IPeerPlayer 界面中。)
我正在使用 MonoGame 框架制作游戏引擎。由于这是一款多人游戏,其他玩家需要了解其他玩家的某些信息,例如位置和速度,通常用于 AI 反应。
我即将实施 Lua 玩家操作脚本。但是,我目前想不出有什么办法让玩家无法修改其他玩家的信息,例如位置和姓名。
例如,假设我在 C# 中有以下 属性:
public Vector2 Pos { get { return pos; } private set { this.pos = value; } }
private Vector2 pos;
看起来不错吧?好吧,不完全是。假设我有一个函数,returns 最近的敌人叫 GetNearestEnemy()
,returns 另一个玩家。因为 Player class 可以访问它自己的属性,所以我可以用其他方法轻松地做这样的事情:
public void DoStuff()
{
Player otherPlayer = GetNearestEnemy();
otherPlayer.Pos = new Vector2(34,151);
}
所以我认为"maybe I could just pass the instance as a parameter."
public void SetPos(Player instance, Vector2 pos)
{
if (instance != this)
return;
else
this.pos = pos;
}
... 并始终将 "this" 作为参数传递。然而,这也有同样的问题:我可以很容易地将 GetNearestEnemy()
传递给该方法,并且我能够设置敌人的位置。
这是我试图阻止的行为类型。有没有办法最好:
- 获取调用方法的实例?
- 在调用对象不知情的情况下隐式设置参数?
或者有其他我没有看到的方法吗?
很遗憾没有。
没有您想要的语言支持。
让我具体说明您想要什么,以便您理解我的回答。
你的问题基本上是这样的:鉴于我有一个对象的 两个 个实例,并且我在这个对象中有一个私有 setter 的属性,是否有是否支持确保实例 #1 无法更改实例 #2 的私有信息的任何语言?
答案是否定的
这将编译并且 "work":
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
:任何类型在同一个程序集或的后代,都可以访问这个
除此之外,您别无选择。所以 "only the same instance can access this" 不作为访问修饰符存在。
那不行。如果 Pos
是一个带有私有 setter 的 属性(实际上),那么他们可以更改它的唯一方法是从 [=12= 中调用 public 方法].类似于 otherPlayer.SetPos(new Vector2(34,151))
,其中 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
属性 只能在 class 中设置。
发布的原始场景可以使用接口来处理,例如IPeerPlayer 只公开其他玩家应该看到的内容并隐藏其他属性(即其他属性不会出现在 IPeerPlayer 界面中。)