来自类或值的C#可空类型参数

时间:2019-11-24 19:29:06

标签: c# generics nullable

我有一个带有受保护成员的C#类,我需要该类可以为空。

该类的目的是返回某个状态的评估结果,该评估结果可以与其他状态的评估结果进行比较以进行排序。我希望默认评估为空,以便我可以知道评估时是否需要执行评估(但在类初始化时不执行评估,因为可能不需要调用它,并且计算可能会很昂贵)

public abstract class EvaluableState<TEvaluation> where TEvaulation : IComparable<TEvaluation>
{
    protected TEvaluation? evaluation; 

    protected EvaluableState() 
    {
        evaluation = null; // cannot convert null to type parameter because it could be a non-nullable value type
    }

    public TEvaluation GetEvaluation() 
    {
        if (evaluation == null)
        {
            evaluation = Evaluate();
        }

        return evaluation;
    }
}

如果我向TEvaluation添加可为空的类型约束,则会得到:

"Circular constraint dependency involving TEvaluation and TEvaluation"

解决这个问题的一种方法是:

evaluation = default;

这将起作用,但是如果类型为Int32,则默认值为0,这可能是允许的值,所以我不能拥有它。

我可以解决的另一种方法是在类型参数中添加一个类约束,但是这种抽象类的实现很可能需要int作为其类型,并且由于上述问题默认解决方案,我认为我无法做到这一点。

有没有一种方法可以让我拥有一个值或一个可以为null的引用类型?

1 个答案:

答案 0 :(得分:1)

根据您的问题陈述,您希望对某件事进行一次评估-在需要时进行评估,并存储结果以备将来使用。这是-惰性语义:

protected Lazy<TEvaluation> evaluation = new Lazy<TEvaluation>(() => Evaluate(...)); 

public TEvaluation GetEvaluation() => evaluation.Value; 

很难以线程安全的方式实现惰性评估,Lazy<T>为您完成了大部分繁重的工作。