我有一个包含许多属性的类,如:
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
,但我仍然希望看到是否有人的替代表示方式比我建议的选项更好。
答案 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)
此处的解决方案
实施例: 数量应该是可以为空的,因为如果设置它的值将永远不会为空
如果Name可能为null(缺少名称),则名称应默认为“”,并且您确定Name永远不会是“”
一个标志,假设Name可能具有空值而你不能想到默认值,那么就应该使用nameSet。默认情况下,此标志为false,当您第一次设置Name的值时,该标志也应设置为true。
如果要以相同的方式处理所有属性,解决方案是创建一个包含Object和布尔标志的类。 Object将存储属性的值,而flag将存储属性是否已初始化,但我不喜欢这样,因为即使不需要它也会创建一个布尔标志。