从被叫方内部返回

本文关键字:返回 方内部 | 更新日期: 2023-09-27 17:57:18

我有一个客户端/服务器架构整合到同一个可执行项目中。 它还支持通过脚本访问用户代码。 因此,在我的代码中,对关键方法进行了大量检查,以确保调用它们的上下文是正确的。 例如,我有很多以下内容:

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,但不是生成异常只是返回。 谢谢!

从被叫方内部返回

您应该考虑升级到另一个抽象级别,并向方法添加元数据以描述这些约束:

[ServerOnly]
public void Spawn(...)
{
    ...
}

然后使用动态代理等 AOP 库来截获对该方法的调用。如果该方法具有 [ServerOnly] 属性,则可以检查正在运行的上下文,如果不正确,则返回。

这种方法将使您非常接近:

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 语句,如果它不在服务器上,则记录,否则只运行函数。

我倾向于同意例外可能是更好的途径,但上述内容符合您的要求。

如果

可能,将描述当前服务器实例的 ServerContext 对象添加到方法参数列表中。

public void Spawn(ServerContext context, Actor2D actor)
{
// do stuff
}

这使得调用方很难在没有有效上下文的情况下执行此方法。这样,您就可以在编译时强制执行规则。