2

我有一个包含许多属性的类,例如:

public class Update
{
    public int Quantity { get; set; }
    public decimal Price { get; set; }
    public string Name { get; set; }
}

的每个实例Update不一定都有每个属性集,系统的另一部分需要知道哪些已设置,哪些未设置。

我有一个选择是制作所有值类型Nullable,因此一个null值将代表未设置的概念。虽然这可行,但我真的不喜欢显式地拥有一些属性Nullable(值类型)和一些由于是引用类型而可以为空的想法。类定义看起来很难看,我不相信空检查在语义上是最好的方法。

我可以创建一个非常相似的类,它对with属性Nullable<T>没有限制。我更喜欢这个选项 using ,但我仍然想看看是否有人有比我建议的选项更好的替代表示。TIsSetNullable

4

6 回答 6

5

你真的应该坚持这里已有的成语。使用内置的可空性。

我看到您对 value 和 ref 类型的可空性不同的担忧。你的解决方法会奏效。但这只是一个表面上的改变,让你受益匪浅。在这种情况下,我建议您更改自己而不是更改代码。尝试使自己适应现有的约定。

编辑:有时您需要能够在通用代码中使值可选。在这种情况下,您需要使用一些自定义选项类型。根据经验,我可以说这是非常讨厌的使用。这不是我选择的解决方案。

于 2012-03-14T15:01:48.263 回答
4

引用类型已经可以有效地为空 - 如果您使用int?,那么您decimal?string每个属性都可以为空。

如果您想将值设置为 null 引用,问题就来了——如果 null 实际上string设置的有效值。

你当然可以写一个Maybe<T>类型,但我不确定我会不会——我可能只会使用 null ......除此之外,对于阅读习惯 C# 习语的代码的其他人来说,它会更熟悉。对于所有“反空”情绪(我在许多情况下确实分享),在某些情况下它是最简单的方法。

于 2012-03-14T15:01:21.163 回答
1

我真的不喜欢有一些属性 Nullable (值类型)和一些不是(引用类型)的想法

引用类型显然可以为空。

string t = null; //is totally valid
于 2012-03-14T15:02:54.207 回答
1

我想说 Nullable 正是您想要用于此目的的。您可以用属性包装成员(就像您已经做的那样),让类在外部显示正常值以及“是否设置”-检查是否需要的方法。但在内部我会使用 Nullable。

于 2012-03-14T15:04:27.170 回答
0

向您推荐一些新的东西......如果您只是谈论一个像 Update 这样的类,成员数量有限,我只会使用 IsSet。

但是,如果您有许多具有这种行为的类似类或许多属性,我可以建议您使用 t4 模板。例如,您可以获取本文中描述的类属性(所需的类型或属性),并根据属性列表自动生成代码(自动实现您想要的任何设计)

如果有人感兴趣,我可以描述更多...

于 2012-03-14T15:10:27.183 回答
0

这里的解决方案

  • 在 null 不是有效选项的地方使用 nullable
  • 在 null 是有效选项但您完全确定不会出现给定值的情况下使用默认值
  • 为每个属性使用一个布尔标志,其中 null 是一个有效值,并且您不能命名一个永远不会使用的默认值。

示例:数量应该是可空的,因为如果设置了它的值将永远不会为空

如果 Name 可能为 null(缺少名称)并且您确定 Name 永远不会是“”,则 Name 应默认为“”

如果 Name 可能具有 null 值并且您想不出默认值,则应该使用一个标志,假设应该使用 nameSet。默认情况下,此标志为 false,当您第一次设置 Name 的值时,该标志也应设置为 true。

如果您想以相同的方式处理所有属性,则解决方案是创建一个包含 Object 和布尔标志的类。Object 将存储属性的值,flag 将存储属性是否已初始化,但我不喜欢这样,因为即使不需要它也会创建一个布尔标志。

于 2012-03-14T15:16:09.417 回答