Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference between `x is int?` and `x is int` in C#?

class C<T> where T : struct {
    bool M1(object o) => o is T;
    bool M2(object o) => o is T?;
}

The two methods above seems to behave equally, both when passing null reference or boxed T value. However, the generated MSIL code is a bit different:

.method private hidebysig instance bool M1(object o) cil managed {
    .maxstack 8
    IL_0000: ldarg.1
    IL_0001: isinst !T
    IL_0006: ldnull
    IL_0007: cgt.un
    IL_0009: ret
}

vs

.method private hidebysig instance bool M2(object o) cil managed {
    .maxstack 8
    IL_0000: ldarg.1
    IL_0001: isinst valuetype [mscorlib]System.Nullable`1<!T>
    IL_0006: ldnull
    IL_0007: cgt.un
    IL_0009: ret
}

As you may see, the o is T? expression actually performs type check for Nullable<T> type, despite the fact that nullable types are specially handled by CLR so that C# represents boxed T? value as null reference (if T? has no value) or boxed T value. It seems impossible to get box of Nullable<T> type in pure C# or maybe even in C++/CLI (since runtime handles box opcode to support this "T? => T box / null" boxing).

Am I missing something or o is T? is practically equivalent to o is T in C#?

like image 594
controlflow Avatar asked Mar 07 '17 00:03

controlflow


People also ask

What's the difference between int x and int x?

IIRC int(x); is declaration for x. (int)x; is a type cast whose result is then ignored. But in your case, either has the same meaning, a type cast. The only real difference is int(x) can't use types with spaces in their name.

What is difference between X and X in C?

In C and C++, "x" is of type const char[] which is an array and it is null-terminated (0x00). Whilst 'x' is of type char . The datatype std::string . C++ has support in the standard library for the String datatype, which can be assigned a const char[] .

What is the difference between int and int in C?

Nothing. They are one and the same. The end result is same — we have two integer variables named a and b and they both are uninitialized. What is the difference between * (int *) and (int *) in C (pointers and development)?

What does int x mean in C?

int(x) is a functional notation for type-casting. C++ is a strong-typed language. Many conversions, specially those that imply a different interpretation of the value, require an explicit conversion, known in C++ as type-casting.


1 Answers

According to the spec (emphasis mine), in E is T, non-nullable value types of T and corresponding nullable types are handled the same way:

7.10.10 The is operator

The is operator is used to dynamically check if the run-time type of an object is compatible with a given type. The result of the operation E is T, where E is an expression and T is a type, is a boolean value indicating whether E can successfully be converted to type T by a reference conversion, a boxing conversion, or an unboxing conversion. The operation is evaluated as follows, after type arguments have been substituted for all type parameters:

  • If E is an anonymous function, a compile-time error occurs

  • If E is a method group or the null literal, of if the type of E is a reference type or a nullable type and the value of E is null, the result is false.

  • Otherwise, let D represent the dynamic type of E as follows:

    • If the type of E is a reference type, D is the run-time type of the instance reference by E.
    • If the type of E is a nullable type, D is the underlying type of that nullable type.

    • If the type of E is a non-nullable value type, D is the type of E.

  • The result of the operation depends on D and T as follows:

    • If T is a reference type, the result is true if D and T are the same type, if D is a reference type and an implicit reference conversion from D to T exists, or if D is a value type and a boxing conversion from D to T exists.
    • If T is a nullable type, the result is true if D is the underlying type of T.
    • If T is a non-nullable value type, the result is true if D and T are the same type.
    • Otherwise, the result is false.
like image 150
AlexD Avatar answered Oct 19 '22 12:10

AlexD