Implicit Nullables Interface Strokes

With VB Option Strict On , why a Nullable(Of T) does not require an explicit cast to the T interface if it requires one to T ?

those.

 Dim x As Integer? = 5 Dim y As Integer Dim z As IComparable y = x ' Fails to compile with error ' "Option Strict On disallows implicit conversions from 'Integer?' to 'Integer'." z = x ' Succeeds 

EDIT: like the (view) shown by @SSS, part of the answer is that the Nullable values ​​are equal, zero and can be Nothing , which is great for a reference such as an interface. Thus, this conversion will always be successful, unlike the conversion to case T (which fails when Nullable does not matter), and therefore it can be considered as an implicit conversion.

Now my question is β€œhow?”. How is the conversion from Nullable(Of T) (which doesn't have its own interfaces) to the T interface theoretically consistent?

I know that the implementation is box Nullable<T> , which effectively breaks the Nullable wrapper, but I confirm the concept here ...

(So, I will look at the documentation and see if they explain it.)

+1
source share
3 answers

While I have not read the documentation yet, I will try to answer:

Firstly, the answer at a higher level is that casting a Nullable to an interface is β€œsafe” and will not be thrown away, therefore it is logically a Widening operator and should not be explicit (compared to casting in T when .HasValue is False , it throws, so it should not be implicit with Option Strict On ).

However, technically the β€œhow” is a little incomprehensible: although some of the Nullable characteristics are encoded in metadata accessible through reflection, most of its β€œmagic” is hidden in:

  • runtime behavior of the box on Nullable (and thus the compiler knows when to leave the "climb" to it) and
  • other points made by Eric Lippert in his answer to C # and their equivalent in VB.NET.

Similar to S. A Somasegar post informing of changes to late-beta Nullable support for VS2k5 is also relevant.

0
source

I do not see a problem?

 y = x 

may fail because x may contain the value Nothing, but y may not hold the value Nothing. The IComparable interface allows you to compare integers with Nothing, so the purpose is beautiful.

Please note that if you change it in a circle:

 x = y 

then this is done because each y value can be assigned to x.

You can confirm that integers can be compared to Nothing as follows:

 MsgBox(5.CompareTo(Nothing)) 
+1
source

From what I can say in vb.net, the interfaceVariable = nullableVariable is essentially equivalent to interfaceVariable = if(nullableVariable.HasValue, CType(nullableVariable.Value, interfaceType), Nothing) . The C # compiler seems to handle things the same way: interfaceVariable = nullableVariable; becomes interfaceVariable = nullableVariable.HasValue ? (interfaceType)nullableVariable.Value : null; interfaceVariable = nullableVariable.HasValue ? (interfaceType)nullableVariable.Value : null; .

If the type nullableValue.Value implements the interface, then nullableVariable.Value will either return the result of the value type or throw an exception. Since there is a guaranteed conversion of the box from the return value to the interface, the throw will be legal. The only way the code described above could be completed is that if a null variable is written between calls to HasValue and Value , such HasValue will see the variable as non-empty, but Value see it as null and throw an exception. I believe that the entry interfaceVariable = nullableVariable just checks for invalidation once, so an exception cannot occur; instead, an undefined value is obtained in the box.

0
source

Source: https://habr.com/ru/post/901867/


All Articles