简体   繁体   English

可空 <Nullable> 或可选 <Nullable> 在C#中

[英]Nullable<Nullable> or Optional<Nullable> in C#

Since the first comment on this question will probably be why and the why is what likely makes this not a duplicate question: I have a value type variable (of type decimal if that matters) that has three valid states: has value | null | unspecified 由于在这个问题上的第一个评论可能会是为什么以及为什么就是有可能使这不是一个重复的问题:我有一个值类型变量有三个有效状态(如果该事项十进制类型): has value | null | unspecified has value | null | unspecified has value | null | unspecified . has value | null | unspecified It would be best to represent all three of these states without a custom class. 最好在没有自定义类的情况下代表所有这三个状态。 Also, 0.0m and any other decimal value are valid. 同样, 0.0m和任何其他十进制值均有效。 Unfortunately, Nullable<Nullable<decimal>> is not valid in C#. 不幸的是, Nullable<Nullable<decimal>>在C#中无效。 What is the best way to do this? 做这个的最好方式是什么?

UPDATE: 更新:

Eric's comments below caused me to think about this a bit differently. 埃里克(Eric)下面的评论使我对此有所不同。 Coming at the question above as a software architect, the core philosophical question is how to handle the case where null can represent multiple meanings. 作为软件架构师,上述问题的核心哲学问题是如何处理null可以代表多种含义的情况。 The particular example that motivated this question is: 激发此问题的特定示例是:

In our system, there are tables with product offerings (price, minimum order quantity, some user defined values, etc). 在我们的系统中,有些表包含产品(价格,最小订单数量,一些用户定义的值等)。 The tables have hierarchy. 这些表具有层次结构。 In order to compute the offer values in the child table the "parent offers" need to be considered. 为了计算子表中的报价,需要考虑“父报价”。 The idea is for null to represent the case where a constraint has been removed and null(null) (for lack of a better syntax) to imply no change to the parent value. 这个想法是用null表示删除约束的情况,而null(null) (因为缺少更好的语法)表示不更改父值。

Now, granted, C# is used (abused?) in a strictly functional manner by us, consequence being that needs are sometimes orthogonal to C#'s purpose. 现在,理所当然地,我们以严格的功能方式使用(滥用?)C#,结果是有时需求与C#的目的正交。 Hopefully the next version of C# has discriminated unions which would be perfect for this. 希望C#的下一个版本可以区分工会,这将是完美的选择。

If you absolutely, positively, do not want to use a custom class or enum, I would say your best option is to use KeyValuePair<decimal, T> where T is some representation of your 3 options ( string for "unspecified"/"has value"/"null", int for -1/0/1, as you like) 如果你绝对,积极,不希望使用自定义类或枚举,我会说你最好的选择是使用KeyValuePair<decimal, T>其中T是你3个选择一定的代表性( string为“未指定” /“有值“ /” null“,根据需要为-1/0/1的int

I feel like this is pretty bad practice, but as per your specifications of no custom class, that's the best I've got. 我觉得这是很糟糕的做法,但是根据您对无自定义类的要求,这是我所拥有的最好的。

Another non-ideal, but possibly workable, solution might be to use a Tuple<decimal?, bool>: 另一个非理想但可行的解决方案可能是使用Tuple <decimal ?, bool>:

Tuple.Create<decimal?, bool>(null, true); //specified null
Tuple.Create<decimal?, bool>(null, false); //unspecified null
Tuple.Create<decimal?, bool>(1.0m, true);  //specified value
Tuple.Create<decimal?, bool>(1.0m, false); //??? insanity

I recommend to write your own implementation of such concept. 我建议您自己编写这种概念的实现。

Minimal version may look like this: 最低版本可能如下所示:

sealed class Assignable<T>
{
    private readonly isAssigned;
    private readonly T value;

    public Assignable()
    {
    }

    public Assignable(T value)
    {
        this.value = value;
        this.isAssigned = true;
    }

    public T Value
    {
        get
        {
            if (!isAssigned) throw new InvalidOperationException();
            return value;
        }
    }

    public bool IsAssigned
    {
        get { return isAssigned; }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM