Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
164 views
in Technique[技术] by (71.8m points)

c# - Why does the == operator work for Nullable<T> when == is not defined?

I was just looking at this answer, which contains the code for Nullable<T> from .NET Reflector, and I noticed two things:

  1. An explicit conversion is required when going from Nullable<T> to T.
  2. The == operator is not defined.

Given these two facts, it surprises me that this compiles:

int? value = 10;
Assert.IsTrue(value == 10);

With the code value == 10, either value is being magically converted to an int (hence allowing int's == operator to be used, or the == operator is being magically defined for Nullable<int>. (Or, I presume less likely, Reflector is leaving out some of the code.)

I would expect to have to do one of the following:

Assert.IsTrue((value.Equals(10)); // works because Equals *is* defined
Assert.IsTrue(value.Value == 10); // works because == is defined for int
Assert.IsTrue((int?)value == 10); // works because of the explicit conversion

These of course work, but == also works, and that's the part I don't get.

The reason I noticed this and am asking this question is that I'm trying to write a struct that works somewhat similarly to Nullable<T>. I began with the Reflector code linked above, and just made some very minor modifications. Unfortunately, my CustomNullable<T> doesn't work the same way. I am not able to do Assert.IsTrue(value == 10). I get "Operator == cannot be applied to operands of type CustomNullable<int> and int".

Now, no matter how minor the modification, I would not expect to be able to do...

CustomNullable<T> value = null;

...because I understand that there is some compiler magic behind Nullable<T> that allows values to be set to null even though Nullable<T> is a struct, but I would expect I should be able to mimic all the other behaviors of Nullable<T> if my code is written (almost) identically.

Can anyone shed light on how the various operators of Nullable<T> work when they appear not to be defined?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Given these two facts, it surprises me that this compiles

Given only those two facts, that is surprising.

Here's a third fact: in C#, most operators are 'lifted to nullable'.

By "lifted to nullable", I mean that if you say:

int? x = 1;
int? y = 2;
int? z = x + y;

then you get the semantics of "if either x or y is null then z is null. If both are not null then add their values, convert to nullable, and assign the result to z."

The same goes for equality, though equality is a bit weird because in C#, equality is still only two-valued. To be properly lifted, equality ought to be three-valued: x == y should be null if either x or y is null, and true or false if x and y are both non-null. That's how it works in VB, but not in C#.

I would expect I should be able to mimic all the other behaviors of Nullable<T> if my code is written (almost) identically.

You are going to have to learn to live with disappointment because your expectation is completely out of line with reality. Nullable<T> is a very special type and its magical properties are embedded deeply within the C# language and the runtime. For example:

  • C# automatically lifts operators to nullable. There's no way to say "automatically lift operators to MyNullable". You can get pretty close by writing your own user-defined operators though.

  • C# has special rules for null literals -- you can assign them to nullable variables, and compare them to nullable values, and the compiler generates special code for them.

  • The boxing semantics of nullables are deeply weird and baked into the runtime. There is no way to emulate them.

  • Nullable semantics for the is, as and coalescing operators are baked in to the language.

  • Nullables do not satisfy the struct constraint. There is no way to emulate that.

  • And so on.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...