gpt4 book ai didi

c# - 如何在C#中设计一个不会失效的DataType

转载 作者:行者123 更新时间:2023-11-30 14:50:28 25 4
gpt4 key购买 nike

这是一个只能讨论,不能真正回答的问题。

我的问题是:我有一个复杂的渲染应用程序和许多原始数据类型,例如:

  • 颜色
  • 字体大小
  • 字体家族
  • 厚度
  • ...

它们都代表一个值,例如Color = Value(uint32), FontFamily = Name(字符串)

我想以某种方式设计数据类型,使它们不会变得无效,并且您无法将无效值传递给方法。它们应该是不可变的。

所以我的第一个想法是将它们定义为结构,但如何处理初始化器(在结构中,您不能覆盖默认构造函数,也不能为您的字段设置初始化器。

例如:FontSize 必须在 4 到 100 之间。

一种解决方案可能是以下设计:

struct FontSize
{
readonly in size;

public int Size
{
get { return size >= 4 && size <= 100 ? size : DefaultSize; }
}

public FontSize(int size)
{
Guard.IsBetween(size, 4, 100, nameof(size)); // Throws ArgumentException
this.size = size;
}
}

这意味着

FontSize a;
FontSize b = new FontSize(14);
bool equal = a == b; // True

这有点奇怪。

你会如何设计这样的数据类型?

编辑:抱歉,我错过了要点,我会在构造函数中进行验证。但是结构的问题是仍然有默认的构造函数。对于类,我可以有空引用。

所以重点是,你只能拥有

  1. 在构造函数中进行验证的类 => 您必须检查 Null-Refs,并且您没有获得变量和属性的有效默认值

  1. 构造一个丑陋的属性来解决默认构造函数的问题。 => 没有 Null Refs,但我觉得很奇怪。

最佳答案

您正在尝试做的是一件好事。如果您创建的域类不能包含无效数据,那么您的所有检查都在一个地方,而不是在使用类的任何地方检查无效值。

答案是

  • 使用只读属性
  • 传递用于在构造函数中填充这些值的值
  • 在构造函数中验证

或者如果您不希望验证存在于类本身中(可能有原因,比如更复杂的验证),您可以

  • 仍然使用只读属性
  • 将构造函数设为私有(private)
  • 使用静态“创建”方法。它调用构造函数,创建一个新对象,对其进行验证(可能使用某种扩展方法),然后返回有效对象或抛出异常。

抱歉,还有一个建议 - 实际上我最喜欢这个:

  • 仍然使用只读属性
  • 将构造函数设为内部
  • 在与您的类型相同的程序集中创建一个单独的构建器类。该类是 public,但您的类型的构造函数是 internal。这样,程序集外部的类只能访问构建器类,将参数传递给它,然后它验证参数并创建类实例或抛出异常。

优点

  • 验证仍然不在您的数据类中
  • 您可以拥有多个具有不同验证参数的构建器类。因此,如果您需要具有不同验证要求的不同版本的数据类,则不必修改该类 - 您只需创建一个不同的构建器类或向现有构建器类添加一个方法。但您始终可以控制消费者如何创建您的类(class)。

反对

  • 因为构造函数是内部的,所以同一程序集中的其他类可以创建无效的实例。

关于c# - 如何在C#中设计一个不会失效的DataType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36633834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com