Reputation: 7565
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:-
is
checks whether the type of an given object is compatible with the new object type. This is a Boolean type..returns either true or false
as
checks whether the type of an given object is compatible with the new object type. It returns non-null if given object is compatible with new one, else null.. This throws an exception.
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
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
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
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
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
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