c# - 验证对象/结构而不会失败

标签 c# validation

假设我们有一个巨大的数字笛卡尔坐标列表 (5;3)(1;-9) 等。为了在 oop 中表示一个点,我创建了一个结构/对象 (c#):

public struct Point
{
    public int X, Y { get; }

    public Point(int x, int y)
    {
        // Check if x,y falls within certain boundaries (ex. -1000, 1000)
    }
}

我使用结构的方式可能是错误的。我想通常你不会使用构造函数,但这不是重点。

假设我想添加一个包含 1000 个点的列表,但无法保证这些坐标落在边界内。简单地说,如果该点无效,则毫不费力地移至下一个点并通知用户。至于对象,我认为 Point 应该自己负责实例化和验证,但我不确定在这种特殊情况下如何处理它。调用者事先检查 x、y 是最简单的方法,但感觉不对,因为调用者必须处理应驻留在 Point 中的逻辑。

在不失败和违反 SRP 的情况下,验证和处理不正确坐标的最合适方法是什么?

最佳答案

你不能在构造函数中这样做;构造函数要么成功运行,要么不成功。如果不是,那是因为引发了异常,所以,无声地失败就这么多了。您可以捕获异常,但这基本上意味着您将异常用作控制流机制,这是一个很大的禁忌,不要那样做!

一种类似于您所想的解决方案是使用静态工厂方法:

public struct Point
{
    public static bool TryCreatePoint(int x, int y, Bounds bounds, out Point point)
    {
         if (x and y are inside bounds)
         {
             point = new Point(x, y); 
             return true;
         }

         point = default(Point);
         return false;
    }

    //...
}

并且添加点到列表的代码应该基于创建成功。

有趣的事实:如果您使用的是 C# 7,代码看起来会更简洁:

public static (bool Succesful, Point NewPoint) TryCreatePoint(int x, int y, Bounds bounds)
{
     if (x and y are inside bounds)
         return (true, new Point(x, y));

     return (false, default(Point));
}

关于c# - 验证对象/结构而不会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41630912/

相关文章:

perl - 如何将枚举类型验证为 Perl 子例程参数?

javascript - HTML5 表单验证?比警告框更多的 'elegant'?

c# - 数据验证属性和自定义资源管理器

c# - 这个 Lazy<T> 被认为是单例吗?

c# - 如何创建一个返回匿名类型的 IEnumerable 的方法

c# - New-MailContact 的等效 API

c# - Unity 4.6 编辑器,使用预定义数据创建脚本

c# - CodeContracts 无法证明简单的保证

jquery - 如何更改错误消息 CSS 样式(欧芹)

asp.net - 在用户控件中公开 ContentPlaceHolder