What is the type of null literal?

D ear everything, I wonder what type of null literal is in C #?

In Java, the null literal has a special null type :

There is also a special null type, a null expression type that does not have a name. Since the null type does not have a name, it is not possible to declare a variable of the null type or apply to the null type. A null reference is the only possible value of an expression of null type. A null reference can always be applied to any reference type.

In C ++ 11, there is nullptr (the recommended version of the old null buddy), which is of type std::nullptr_t .

I searched MSDN near C #, but the spec seems to say nothing about this.

+48
language-lawyer c #
Nov 20 '11 at 20:44
source share
3 answers

According to ECMA C # language specification :

9.4.4.6 Zero literal:

A null literal type is a null type (§11.2.7).

11.2.7 Zero type:

A null literal (§9.4.4.6) evaluates to a null value that is used to indicate a reference that does not point to any object or array, or the absence of a value. The null type has a single value, which is a null value. Therefore, an expression whose type is null can evaluate only a null value. It is impossible to explicitly write a null type and, therefore, not use it in the declared type. Moreover, a null type can never be a type deduced for a type parameter (§25.6.4)

So, to answer your question, null is a native type - a null type.

Although it is strange, as it is not mentioned in the C # 4.0 language specification or the C # 3.0 language specification, it is mentioned in the C # 3.0 review, the C # ECMA specification, and the C # 2.0 language specification .

+51
Nov 20 '11 at 20:50
source share

UPDATE: This question was the subject of my blog in July 2013. Thanks for the great question!




J. Commer's answer is correct (and good for them to do what, obviously, there was a lot of speculation!), But I thought I would add a bit of historical perspective.

When Mads and I sorted out the exact wording of the various parts of the specification for C # 3.0, we realized that the "null type" was strange. This is a "type" with a single value. This is the "type" of which "Reflection" knows nothing. This is a “type” that does not have a name that GetType never returns, which you cannot specify as the type of a local variable or field or anything else. In short, it really is a “type” that should only make the type system “complete”, so that every compile-time expression has a type.

Except that C # already had expressions that did not have types: method groups in C # 1.0, anonymous methods in C # 2.0, and lambdas in C # 3.0 are not type. If all these things cannot have any type, we realized that the “null” should not have a type either. Therefore, we removed references to the useless "null type" in C # 3.0.

As part of the implementation, Microsoft implementations from C 1.0 through 5.0 all have an internal object to represent the "null type". They also have objects to represent non-existent lambda types, anonymous methods, and method groups. This choice of implementation has a number of pros and cons. On the pro side, the compiler can query the type of expression and get a response. On the other hand, this means that sometimes errors in the analysis of types that the compiler really should have broken instead cause semantic changes in programs. My favorite example of this is that in C # 2.0 you can use the invalid expression "null? Null"; due to an error, the compiler cannot mark this as an erroneous use of the operator ?? , and then concludes that the type of this expression is a "null type", although it is not a null literal. This then leads to many other errors in the stream as the type analyzer tries to understand the type.

At Roslyn, we probably won't use this strategy; rather, we just baked into the compiler implementation that some expressions are not of type.

+41
Nov 21 '11 at 16:50
source share

Although there is no runtime type, null can be applied to the type at compile time, as shown in this example.

At run time, you may find that the stringAsObject variable contains a string , not just an object , but you cannot find any type for the nullString and nullStringAsObject .

 public enum Answer { Object, String, Int32, FileInfo }; private Answer GetAnswer(int i) { return Answer.Int32; } private Answer GetAnswer(string s) { return Answer.String; } private Answer GetAnswer(object o) { return Answer.Object; } [TestMethod] public void MusingAboutNullAtRuntimeVsCompileTime() { string nullString = null; object nullStringAsObject = (string)null; object stringAsObject = "a string"; // resolved at runtime Expect.Throws(typeof(ArgumentNullException), () => Type.GetTypeHandle(nullString)); Expect.Throws(typeof(ArgumentNullException), () => Type.GetTypeHandle(nullStringAsObject)); Assert.AreEqual(typeof(string), Type.GetTypeFromHandle(Type.GetTypeHandle(stringAsObject))); Assert.AreEqual(typeof(string), stringAsObject.GetType()); // resolved at compile time Assert.AreEqual(Answer.String, this.GetAnswer(nullString)); Assert.AreEqual(Answer.Object, this.GetAnswer(nullStringAsObject)); Assert.AreEqual(Answer.Object, this.GetAnswer(stringAsObject)); Assert.AreEqual(Answer.Object, this.GetAnswer((object)null)); Assert.AreEqual(Answer.String, this.GetAnswer((string)null)); Assert.AreEqual(Answer.String, this.GetAnswer(null)); } // Uncommenting the following method overload // makes the last statement in the test case ambiguous to the compiler // private Answer GetAnswer(FileInfo f) { return Answer.FileInfo; } 
0
Apr 05 2018-12-12T00:
source share



All Articles