简体   繁体   中英

C# Custom generic struct with same compiler behavior as Nullable<T>

Behold the following example with System.Nullable<T> in C#.

int x = 5;
int? y = 3;
int? result = x + y; //no compiler warning

It makes sense that the compiler can figure out that T is an int , thus it can use the operator.
Also in

int x = 5;
int? y = 3;
bool result = x == y; //no compiler warning

it makes sense, if x was null , the expression would be false . The compiler doesn't mind.

Now I'm trying to create a lookalike Nullable<T> class. Let's call it Lookable<T> .

[Serializable]
public struct Lookable<T> where T : struct
{
    public Lookable(T value)
    {
        Value = value;
    }

    public T Value { get; }

    public override bool Equals(object other)
    {
        return other != null && Value.Equals(other);
    }

    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }

    public override string ToString()
    {
        return Value.ToString();
    }

    public static implicit operator Lookable<T>(T value)
    {
        return new Lookable<T>(value);
    }

    public static explicit operator T(Lookable<T> value)
    {
        return value.Value;
    }
}

The idea here is straight from .NET's source code . In my case I'm just omitting the HasValue property. Now this example would work:

int x = 6;
Lookable<int> y = x;
Lookable<int> z = 4;

The compiler can infer the types here because of the implicit operator correct?
What I don't understand is that this example will make the compiler unhappy:

int x = 5;
Lookable<int> y = 3;
var result1 = x + y; //compile error
var result2 = x == y; //compile error

The compiler is giving me the message:

Operator cannot be applied to operands of type ' int ' and ' Lookable<int> '.

Why not? And why is it possible with Nullable<T> ? I can't find it anywhere in the source code. Would it also be possible for Lookable<T> ?

The code for this isn't in Nullable<T> - it is in the C# compiler, in particular "lifted operators" in the specification, and how they apply specifically to System.Nullable<T> . The specification references are in this answer .

You cannot reproduce the Nullable<T> behaviour in your own types. It has special handling by both the compiler and the runtime (boxing, etc).

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