c# - 在 API 中对参数验证抛出异常是否被认为是一种好的做法?

标签 c# function exception

像我对 TryPassNameValidation 函数所做的那样,在函数参数验证时抛出异常是否被视为一种好的做法,如果:

  1. 代码没有直接面向用户界面。它是 API 的一部分。
  2. 重要的是执行不会因参数错误而继续。
  3. 我想要良好的可读性和流畅性。

我还考虑过返回一个验证对象,如 answer 中所述但是这种编程风格让我想起了 GoLang functions handle errors .我认为异常是为了防止我们不得不这样做而发明的。

    public void AddChildStructureLevel(Structure childStructureLevel)
    {
        try
        {
            TryPassNameValidation(childStructureLevel.Name); // throws if something is wrong
            Children.Add(childStructureLevel);
        }
        catch (ArgumentException ae)
        {
            throw new ArgumentException($"Provided structure name {childStructureLevel.Name} is invalid.", ae);
        }

        Trace.WriteLine($"Added new child structure level to parent structure children.");
    }

    private void TryPassNameValidation(string structureName)
    {
        TryPassingStructureNameMinMaxLength(structureName); 
        TryPassingStructureNameUnique(structureName);
    }

    private void TryPassingStructureNameMinMaxLength(string structureName)
    {
        bool nameIsTooLong  = structureName.Length >= maxLengthStructureName;
        bool nameIsTooShort = structureName.Length <= minLengthStructureName;

        if (nameIsTooLong) throw new ArgumentException($"Structure name is too long. Max {maxLengthStructureName} characters.");
        if (nameIsTooShort) throw new ArgumentException($"Structure name is too short. Min {minLengthStructureName} characters.");
    }

    private void TryPassingStructureNameUnique(string childName)
    {
        foreach (Structure child in Children) //TODO: recurse over children.children
            if (child.Name == childName) throw new ArgumentException($"Structure level name {childName} already exists.");
    }

最佳答案

我发现这段代码很难理解,这与您的目标背道而驰。验证是通过嵌套调用和非显而易见的控制流(异常)完成的。我发现每个方法开头的常用 if ... throw; 序列更容易理解。部分原因是几乎所有的验证代码看起来都是这样。

TryPassingStructureNameUnique 应该使用 Any 编写。这样做之后,它适合一行,并且可以在提到的 if ... throw; 验证模式中使用。

bool nameIsTooLong 真的很冗长。这些条件是微不足道的。他们应该只使用 if ... throw; 模式。

除此之外,我认为这种设计是一个有效的选择。这不是一个容易的选择。如果可以的话,我不会那样做。

如果有效性是您的核心概念,请考虑将每个 Structure 包装在 ValidatedStructure 包装器类中。施工验证。通过这种方式,您可以通过目测了解给定的 Structure 是否已经过验证。

关于c# - 在 API 中对参数验证抛出异常是否被认为是一种好的做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36390959/

相关文章:

function - 最佳实践 : function return value or byref output parameters?

scala - ScalaTest 3 中的评估和生产去了哪里?

c++ - 智能指针类的线程安全复制赋值运算符

c# - 抽象方法中的可选参数?是否可以?

c# - 更新 Windows 服务程序集而不重新启动它?

c# - 响应式扩展测试调度程序模拟时间流逝

javascript - 通过字符串名称调用 "local"函数而不使用 eval?

c - 为c中的指针结构成员赋值

java - 读取每个单词和后面的两个单词并检查java中的一些条件

c# - 如何使用 WampSharp 处理错误和连接关闭