如何防止.NET运行时中的静态变量共享?

时间:2020-03-05 18:59:05  来源:igfitidea点击:

我正在开发一个使用类似Robocode的编程模型的游戏(C#):参与者继承了基本类并添加了战略行为。然后,游戏会加载参与者的班级实例,然后比赛开始。不幸的是,参与者可以通过在竞争对手类的实例之间共享静态变量来"作弊"。

如何防止.NET语言的Class实例之间共享静态变量?我知道这是通过在Java中为每个实例使用单独的ClassLoader来完成的。什么是.NET等效项?

提前致谢...

关于解决方案的注意事项:我的测试表明,仅当加载扩展了MarshalByRefObject的Class时,单独的AppDomain才起作用。我想这很有意义,如果我们只是加载一个Serializable类,则将该类复制到当前的AppDomain中,因此来自另一个AppDomain的另一个对象将共享其静态变量。 MarshalByRefObject保证仅将代理加载到当前AppDomain中,并且静态变量保留在加载的AppDomain中。另请参阅:http://blogs.msdn.com/ericlippert/archive/2004/05/27/143203.aspx

解决方案

回答

将每个竞争对手加载到不同的AppDomain中。

回答

静态变量是针对每个AppDomain的,因此我们可以考虑使用不同的AppDomain,但是我完全不知道还有其他后果。

否则,我们可以使用反射预先检查类,并拒绝任何具有静态成员的类。

回答

我没有具体的答案,但我将看看.NET Terrarium项目。所有参与者都是用户加载的DLL。他们做了很多整洁的工作,以防止不安全和作弊的代码加载/执行。

贾斯汀·罗杰斯(Justin Rogers)撰写了大量有关Terrarium实现细节的文章。

回答

if(typeof(CompetitorClass).GetFields(BindingFlags.Static))
{
 // take necessary steps against cheater!
}

回答

那是我正在研究的真正Robocode的.NET插件中的解决方案。

回答

[ThreadStatic]属性对我们有用吗?只要玩家处于不同的线程中,它就可以解决问题。从MSDN站点:

A static (Shared in Visual Basic)
  field marked with
  ThreadStaticAttribute is not shared
  between threads. Each executing thread
  has a separate instance of the field,
  and independently sets and gets values
  for that field. If the field is
  accessed on a different thread, it
  will contain a different value.