我将客户端/服务器架构集成到同一个可执行项目中。它还支持通过脚本访问用户代码。因此,在我的代码中,对关键方法进行了大量检查,以确保调用它们的上下文是正确的。例如,我有很多以下内容:
public void Spawn(Actor2D actor)
{
if (!Game.Instance.SERVER)
{
Util.Log(LogManager.LogLevel.Error, "Spawning of actors is only allowed on the server.");
return;
}
//Do stuff.
}
我想减少这些重复的代码。 C#中是否存在能够提供类似:
等功能的功能public void Spawn(Actor2D actor)
{
AssertServer("Spawning of actors is only allowed on the server.");
//Do stuff.
}
即使像" [MethodNameOfPreviousCallOnStack]这样的通用消息也只能在服务器上调用。"是可以接受的。但它也必须也从调用者返回(在这种情况下是Spawn()
),就像中止一样。与assert
类似,但不是生成异常而是返回。谢谢!
答案 0 :(得分:2)
您应该考虑进入另一个抽象级别并向方法添加元数据来描述这些约束:
[ServerOnly]
public void Spawn(...)
{
...
}
然后使用像Dynamic Proxy这样的AOP库来拦截对该方法的调用。如果该方法具有[ServerOnly]
属性,那么您可以检查您正在运行的上下文,然后返回它是否不正确。
答案 1 :(得分:1)
这种方法会让你非常接近:
public void RunOnServerOnly(Action execFunc, string errorMessage)
{
if (!Game.Instance.SERVER)
{
Util.Log(LogManager.LogLevel.Error, errorMessage);
}
else
{
execFunc();
}
}
然后你称之为:
RunOnServerOnly(() => Spawn(newActor), "Spawning of actors is only allowed on the server.");
说明:
要删除重复的代码,您有一个执行检查和记录的功能。如果检查通过,您可以执行操作(通用委托)。它运行if语句,如果它不在服务器上则记录,否则只运行该函数。
我倾向于同意例外情况可能是更好的选择,但上述情况符合您的要求。
答案 2 :(得分:0)
如果可能,请将描述当前服务器实例的ServerContext
对象添加到方法参数列表中。
public void Spawn(ServerContext context, Actor2D actor)
{
// do stuff
}
这使得调用者很难在没有有效上下文的情况下执行此方法。这样,您就可以在编译时强制执行规则。