IS Keyword
IS does not compare objects, it checks the object for its type.
For example:
"abc" string gives TRUE,
"abc" is int gives False,
"abc" is "abc" gives compile time error because it cannot be used to compare two types.
So, a comparison is not done by IS, only checking is done.
- namespace IsAndAsOperators {
- class Person {
- public int Id {
- get;
- set;
- }
- public string Name {
- get;
- set;
- }
- public int Age {
- get;
- set;
- }
- }
- class Alien {
- public int ID {
- get;
- set;
- }
- public string Name {
- get;
- set;
- }
- public int Age {
- get;
- set;
- }
- }
- class Program {
- static void Main(string[] args) {
- Person pobj = new Person();
- pobj.Id = 1;
- pobj.Name = "GOGO";
- pobj.Age = 15;
- Alien aobj = new Alien();
- aobj.ID = 20;
- aobj.Name = "POGO";
- aobj.Age = 25;
-
- bool issame = (aobj is Person);
- System.Console.WriteLine("Alien is a Person ?: {0}", issame.ToString());
- issame = (pobj is Person);
- System.Console.WriteLine("Person is a Person ?: {0}", issame.ToString());
- System.Console.ReadLine();
- }
- }
- }
Inheritance Case in IS operator
Now what happens if Alien inherit from Person (alien that evolved as earth Person over time) .
- namespace IsAndAsOperators {
- class Person {
- public int Id {
- get;
- set;
- }
- public string Name {
- get;
- set;
- }
- public int Age {
- get;
- set;
- }
- }
- class Alien: Person {
- public int ID {
- get;
- set;
- }
- public string NAME {
- get;
- set;
- }
- public int AGE {
- get;
- set;
- }
- }
- class Program {
- static void Main(string[] args) {
- Person pobj = new Person();
- pobj.Id = 1;
- pobj.Name = "GOGO";
- pobj.Age = 15;
- Alien aobj = new Alien();
- aobj.ID = 20;
- aobj.Name = "POGO";
- aobj.Age = 25;
-
- bool issame = (aobj is Person);
- System.Console.WriteLine("Alien is a Person ?: {0}", issame.ToString());
- issame = (pobj is Person);
- System.Console.WriteLine("Person is a Person ?: {0}", issame.ToString());
- System.Console.ReadLine();
- }
- }
- }
AS operator
The AS operator gives a reference of various types. Say object r1 = "abc", then string r2 = r1 as string means r2 is the same as r1 but as a string, whereas Uri r3 = r1 as Uri means r3 is null because r1 wasn't a Uri so this couldn't work.
So the AS operator gives a reference if it can be done, else it gives NULL.
CODE
- namespace IsAndAsOperators {
- class Person {
- public int Id {
- get;
- set;
- }
- public string Name {
- get;
- set;
- }
- public int Age {
- get;
- set;
- }
- }
- class Alien {
- public int ID {
- get;
- set;
- }
- public string Name {
- get;
- set;
- }
- public int Age {
- get;
- set;
- }
- }
- class Program {
- static void Main(string[] args) {
- Person pobj = new Person();
- pobj.Id = 1;
- pobj.Name = "GOGO";
- pobj.Age = 15;
- Alien aobj = new Alien();
- aobj.ID = 20;
- aobj.Name = "POGO";
- aobj.Age = 25;
-
- System.Console.WriteLine("Alien is a Person ?: {0}", useAS(aobj));
- System.Console.WriteLine("Person is a Person ?: {0}", useAS(pobj));
- System.Console.ReadLine();
- }
- private static string useAS(dynamic aobj) {
-
- Person obj = aobj as Person;
- if (obj != null) return "This is a Person and his name is " + obj.Name;
- return "Not a Person";
- }
- }
- }
AS with Inheritance
Now what happens if Alien inherits from Person (alien that evolved as earth Person over time).
- namespace IsAndAsOperators
- {
- class Person {
- public int Id
- {
- get;
- set;
- }
- public string Name
- {
- get;
- set;
- }
- public int Age
- {
- get;
- set;
- }
- }
- class Alien: Person {}
- class Program {
- static void Main(string[] args)
- {
- Person pobj = new Person();
- pobj.Id = 1;
- pobj.Name = "GOGO";
- pobj.Age = 15;
- Alien aobj = new Alien();
- aobj.Id = 20;
- aobj.Name = "POGO";
- aobj.Age = 25;
-
- System.Console.WriteLine("Alien is a Person ?: {0}", useAS(aobj));
- System.Console.WriteLine("Person is a Person ?: {0}", useAS(pobj));
- System.Console.ReadLine();
- }
- private static string useAS(dynamic aobj)
- {
-
- Person obj = aobj as Person;
- if (obj != null) return "This is a Person and his name is :" + obj.Name;
- return "Not a Person";
- }
- }
- }
CAST Operator
Let's explain this by the code first approach. We will see various ways to cast objects.
Let us say we have:
- void TestProgram(object o, EventArgs e)
- {
-
- string s = (string) o;
-
- string s = o as string;
-
- string s = o.ToString();
- }
What is the difference between all these?
Using thoughts of Sander (since he explained this in the best possible way):
- Throws InvalidCastException if o is not a string, otherwise assigns o to s, even if o is null. (Use this for most conversions.)
- Assigns null to s if o is not a string or if o is null. For this reason, you cannot use it with value types (the operator could never return null in that case), otherwise assigns o to s. (Try to never use 2 since if something is not of the right type, I usually expect an exception to occur. I have only seen a need for this return-null type of functionality with badly designed libraries which use error codes, for example, return null = error instead of using exceptions).
- Causes a NullReferenceException if o is null. Assigns whatever o.ToString() returns to s, no matter what type o is. (Use it for when you need the string representation of a non-string object.)
BASIC- (int) value and "value as int" is that the former throws an exception if the conversion fails, whereas the latter returns null.
More details about CAST
We can cast only if we know what type it will be. What it means is explained by Boxing and Unboxing.
Here's the code:
- static string[] args)
-
- {
- short a = 10;
-
- object o = (object) a;
-
- int b = (int) o;
-
- Console.WriteLine(b.ToString());
-
- Console.ReadLine();
- }
Here it is not possible since the compiler does not know how to unbox it. A short can be unboxed as a short only.
However:
- int jjj = (int) (short) ooo;
Reason
When a value is boxed as an Object then when unboxing the compiler does not know to which type it needs to be unboxed to. So if it's a short it needs to generate code to convert it into a short. If it's an int then it needs to generate code for an int and then there are many other complex types. Basically there will be a huge amount of code to generate and it would be very slow.
The code is of course so large that you would want to put it in its own method and just generate a call to it. Rather than do that by default and always generate code that is slow, large and fragile, instead we've decided that unboxing can only unbox to the exact type. If you want to call the slow method that does everything then it's available, you can always call Convert.ToInt32 that does all the analysis at runtime for you. We give you the choice between “fast and precise” or “slow and lax”, and the sensible default is the former. If you want the latter then call the method. So to make life a bit easy, C# 4.0 added the new keyword "Dynamic" instead of "object". We will explain it in the next article.