Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Covariance" of the System.Nullable<> struct

When we have two structs, and one is implicitly convertible to the other, then it seems like the System.Nullable<> versions of the two are also implicitly convertible. Like, if struct A has an implicit conversion to struct B, then A? converts to B? as well.

Here is an example:

struct MyNumber
{
  public readonly int Inner;

  public MyNumber(int i)
  {
    Inner = i;
  }

  public static implicit operator int(MyNumber n)
  {
    return n.Inner;
  }
}

Inside some method:

MyNumber? nmn = new MyNumber(42);
int? covariantMagic = nmn; // works!

In the C# Language Specification Version 4.0 we read that a conversion like this shall exist for "the predefined implicit identity and numeric conversions".

But is it safe to assume that it will also work for user-defined implicit conversions?

(This question might be related to this bug: http://connect.microsoft.com/VisualStudio/feedback/details/642227/)

like image 347
Jeppe Stig Nielsen Avatar asked May 09 '12 14:05

Jeppe Stig Nielsen


People also ask

Can struct be Nullable?

In C# a struct is a 'value type', which can't be null.

What is Nullable in C#?

C# provides a special data types, the nullable types, to which you can assign normal range of values as well as null values. For example, you can store any value from -2,147,483,648 to 2,147,483,647 or null in a Nullable<Int32> variable. Similarly, you can assign true, false, or null in a Nullable<bool> variable.

What is the use of HasValue in C#?

HasValue indicates whether an instance of a nullable value type has a value of its underlying type. Nullable<T>. Value gets the value of an underlying type if HasValue is true . If HasValue is false , the Value property throws an InvalidOperationException.

Are integers Nullable C#?

As you know, a value type cannot be assigned a null value. For example, int i = null will give you a compile time error. C# 2.0 introduced nullable types that allow you to assign null to value type variables.


1 Answers

But is it safe to assume that it will also work for user-defined implicit conversions?

Yes. From section 6.4.2 of the C# 4 spec:

Given a user-defined conversion operator that convers from a non-nullable value type S to a non-nullable value type T, a lifted conversion operator exists that converts from S? to T?. This lifted conversion operator performs an unwrapping from S? to S followed by the user-defined conversion from S to T, followed by a wrapping from T to T?, except that a null-valued S? converts directly to a null-valued T?.

A lifted conversion operator has the same implicit or explicit classification as its underlying user-defined conversion operator. The term "user-defined conversion" applies to the use of both user-defined and lifted conversion operators.

like image 114
Jon Skeet Avatar answered Oct 19 '22 00:10

Jon Skeet