简体   繁体   中英

C# Nullable Type Parameter from Class or Value

I have a C# class with a protected member that I need to be nullable.

The purpose of the class is to return an evaluation of some state that may be compared against some other state's evaluation for sorting. I want the default evaluation to be null, so that I can know if I need to perform the evaluation when the evaluation (but not to perform it when the class is initialized because it may not need to be called and the computation could be costly)

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;
    }
}

If I add a nullable type constraint to TEvaluation I get:

"Circular constraint dependency involving TEvaluation and TEvaluation"

One way that I can get around this is to do:

evaluation = default;

which will work, but if the type is something like Int32 , the default will be 0, which could be an allowed value, so I can't have that.

Another way I can get around this is to add a class constraint to the type parameter, but it likely that the implementation of this abstract class will need int as it's type, and because of the problem with the above default solution, I don't think I can do this.

Is there a way that I can have either a value or a reference type that can be null?

According to your problem statement, you want to evaluate something once - when it's needed and store the result for future use. Which is - lazy semantics:

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

and

public TEvaluation GetEvaluation() => evaluation.Value; 

It's hard to implement lazy evaluation in a thread-safe manner, and Lazy<T> does most of the heavy lifting for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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