Kgn-web
Kgn-web

Reputation: 7565

Is and As keyword in C#

I am trying to get understanding of the difference between is and as keyword in C#

On googling & reading few articles, I got the understanding as below:-

So taking this below I was trying.

class Customer
{

}

class Client
{

}

Main()
{
  Customer cu = new Customer();  
  Client cl = new Client();

 //usage of is 

  var flag = cu is Customer;
  Console.Writeline(flag); //true

 flag = cu is Client;
 Console.writeline(flag); // false

//usage of as
var obj = cu as Customer; 
Console.writeline(obj);


//on the below statement, I was expecting an exception on run time.
 var obj1 = cu as Client;
 //#checkPoint but the above line is giving me Compile time error.

}

It sounds confusing to me why I am getting compile time error on #checkPoint instead based on my understanding I was expecting a run time error as customerObj(cu) is not compatible with Client.

Any suggestion(s) highly appreciated.

Upvotes: 0

Views: 163

Answers (4)

Sean Stayns
Sean Stayns

Reputation: 4244

Have you tried to cast your "cu" in a dynamic object?

 static void Main(string[] args)
    {


        Customer cu = new Customer();
        Client cl = new Client();

        //usage of is 

        var flag = cu is Customer;
        Console.WriteLine(flag); //true

        flag = cu is Client;
        Console.WriteLine(flag); // false

        //convert it to a dynamic object
        dynamic obj = cu;

        //usage of as
        var obj1 = obj as Customer;
        Console.WriteLine(obj);


        //on the below statement, I was expecting an exception on run time.#
        var obj2 = obj as Client;
        Console.WriteLine(obj2);            // <-- this is null!!

        //#checkPoint but the above line is giving me Compile time error.


        Console.ReadKey();

    }

The "obj2" will be null, after running this code, without exceptions.

Why this works and why your code doesn't work, I don't know. I think it's based on the implementation of "as". If you use the "as" statement, then the method behind checks, whether the class are castable or not and in your case, the "as" method know's, that it is not castable and throw's an exception. But if you cast it to an dynamic object, before you use the "as", then the behind method can't check it and returns null.

Upvotes: 0

Lee
Lee

Reputation: 144206

The specification defines when a cast of the form obj as T is valid:

7.10.11 The as operator

An identity (§6.1.1), implicit nullable (§6.1.4), implicit reference (§6.1.6), boxing (§6.1.7), explicit nullable (§6.2.3), explicit reference (§6.2.4), or unboxing (§6.2.5) conversion exists from E to T.

In

var obj1 = cu as Client;

There is no implicit conversion so you need an explicit reference conversion between cu and Client.

The specification defines the explicit reference conversions:

6.2.4 Explicit reference conversions

  • From object and dynamic to any other reference-type.
  • From any class-typeS to any class-typeT, provided S is a base class of T.

Neither of these apply so the cast is invalid. The simplest fix is to change the type of cu to object:

object cu = new Customer();

at runtime cu as Client will evaluate to null.

Upvotes: 2

skynyrd
skynyrd

Reputation: 982

When you say var obj = cu as Client you basically trying to cast cu instance to Client, and since it is not inherited from Client, it returns null.

It is more convenient to give this example for a usecase:

Let's say you have a base class of BaseClass:

public abstract class BaseClass
    {
        protected BaseClass()
        {
        }
    }

and Let's say you have two types derived from BaseClass, Sub1 and Sub2:

public class Sub1 : BaseClass {

}

public class Sub2 : BaseClass {

}

And you have a method in somewhere that takes a BaseClass object and do some instructions according to its sub classes.

private void Method(BaseClass base) {
     var sub1 = base as Sub1;
     var sub2 = base as Sub2;

     if(sub1 != null) {
           // do something specific
     }
     if(sub2 != null) {
           // do something specific
     }
     else
          throw new SubTypeIsNotSupportedException();
}

However is is just for checking an instance type.

if(anInstance is Sub1) {
     Console.WriteLine("It is Sub1!");
}
if(anInstance is Sub2) {
     Console.WriteLine("It is Sub2!");
}
else {
     Console.WriteLine("I don't know what it is!");
}

Upvotes: 1

nvoigt
nvoigt

Reputation: 77364

It's giving you a compile time error, because the type of obj is Customer and whatever comes out of cu as Client will be of type Client.

You will not get an exception at runtime even if you assign to a variable of type Client though. You quoted it yourself:

else null

It will simply result in null.

Upvotes: 1

Related Questions