如何表示可能未设置的数据

时间:2012-03-14 14:58:57

标签: c# nullable data-representation

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

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

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

我得到的一个选项是生成所有值类型Nullable,因此null值将代表未设置的概念。虽然这会起作用,但我并不喜欢明确地使一些属性Nullable(值类型)和一些可以作为引用类型可以为空的想法。类定义看起来很难看,我不相信null检查在语义上是最好的方法。

我可以创建一个与Nullable<T>非常相似的类,它对T具有IsSet属性没有约束。我更喜欢使用此选项来使用Nullable,但我仍然希望看到是否有人的替代表示方式比我建议的选项更好。

6 个答案:

答案 0 :(得分:5)

你真的应该坚持这里先前存在的习语。使用内置的可空性。

我认为你对值和ref类型的可空性的关注是不同的。你的解决方法会起作用。但这只是一种美化改变,让你小心翼翼。我建议您改变自己,而不是在这种情况下更改代码。尽量适应现有的惯例。

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

答案 1 :(得分:4)

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

如果您想将string值设置为空引用,则会出现问题 - 如果null实际上是 设置的有效值。

你肯定可以写一个Maybe<T>类型,但我不确定我会 - 我会可能只使用null ...除了任何东西否则,对于习惯使用C#习语的其他人来说,它会更熟悉。对于所有“反空”的情绪(我在许多情况下分享),有些情况下这是最简单的方法。

答案 2 :(得分:1)

  

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

引用类型显然是可以为空的。

string t = null; //is totally valid

答案 3 :(得分:1)

我会说Nullable正是你想要用于此目的的。 你可以用属性包装成员(就像你已经做的那样)让类向外显示正常值以及“is it set”-methods来检查是否需要。但在内部我会使用Nullable。

答案 4 :(得分:0)

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

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

如果有兴趣的话,我可以更详细地描述一下......

答案 5 :(得分:0)

此处的解决方案

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

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

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

一个标志,假设Name可能具有空值而你不能想到默认值,那么就应该使用nameSet。默认情况下,此标志为false,当您第一次设置Name的值时,该标志也应设置为true。

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