Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"is" operator behaving a bit strangely

Tags:

c#

.net

1) According to my book, is operator can check whether expression E (E is type) can be converted to the target type only if E is either a reference conversion, boxing or unboxing. Since in the following example is doesn’t check for either of the three types of conversion, the code shouldn’t work, but it does:

  long l;     // EDIT - I forgot to add this line of code in my initial post
  int i=100;
  if (i is long) //EDIT - in my initial post I've claimed condition returns true, but it really returns false
           l = i;

2)

a)

    B b;
    A a = new A();
    if (a is B)
        b = (B)a;
    int i = b.l;


    class A { public int l = 100; }
    class B:A { }

The above code always causes compile time error “Use of unassigned variable”. If condition a is B evaluates to false, then b won’t be assigned a value, but if condition is true, then it will. And thus by allowing such a code compiler would have no way of knowing whether the usage of b in code following the if statement is valid or not ( due to not knowing whether a is b evaluates to true or false) , but why should it know that? Intsead why couldn’t runtime handle this?

b) But if instead we’re dealing with non reference types, then compiler doesn’t complain, even though the code is identical.Why?

        int i = 100;
        long l;
        if (i is long)
            l = i;

thank you

like image 214
flockofcode Avatar asked Dec 08 '22 02:12

flockofcode


2 Answers

This has nothing to do with the is operator. The compiler sees that there are two possible paths, only one of which will assign a value to b.

When dealing with value types, the compiler knows that l gets implicitly initialized to the value 0.

like image 64
Stephen Cleary Avatar answered Dec 27 '22 08:12

Stephen Cleary


The real difference is that in the int case, you are talking about the definite assignment of a field (l). Fields are always definitely assigned (even without the =100). In the B case, you are talking about the definite assignment of the local variable (b); local variables do not start as definitely assigned.

That's all it is.


int i=100; if (i is long) //returns true, indicating that conversion is possible

1: I don't think this returns true at all; for me it shows an IDE warning about never being true. Looking in reflector, the compiler completely removes this branch. I guess the compiler is obliged to at least compile on the grounds that it could (in theory) box and test. But it already knows the answer, so it snips it.

2: I still get the "unassigned variable" compiler error; due to "definite assignment"

like image 29
Marc Gravell Avatar answered Dec 27 '22 08:12

Marc Gravell