Difference between is and as keyword - c#

Please tell what is the difference between is and as keyword in C#

is
The is operator checks if an object can be cast to a specific type.
Example:
if (someObject is StringBuilder) ...
as
The as operator attempts to cast an object to a specific type, and returns null if it fails.
Example:
StringBuilder b = someObject as StringBuilder;
if (b != null) ...
Also related:
Casting
The cast operator attempts to cast an object to a specific type, and throws an exeption if it fails.
Example:
StringBuilder b = (StringBuilder)someObject.

The Difference between IS and As is that..
IS - Is Operator is used to Check the Compatibility of an Object with a given Type and it returns the result as a Boolean (True Or False).
AS - As Operator is used for Casting of Object to a given Type or a Class.
Ex.
Student s = obj as Student;
is equivalent to:
Student s = obj is Student ? (Student)obj : (Student)null;

Both is and as keywords are used for type casting in C#.
When you take a look at the IL code of usages of both the keywords, you will get the difference easily.
C# Code:
BaseClass baseclassInstance = new DerivedClass();
DerivedClass derivedclassInstance;
if (baseclassInstance is DerivedClass)
{
derivedclassInstance = (DerivedClass)baseclassInstance;
// do something on derivedclassInstance
}
derivedclassInstance = baseclassInstance as DerivedClass;
if (derivedclassInstance != null)
{
// do something on derivedclassInstance
}
IL code (for above C# code is in the attached image):
The IL code for is keyword usage contains IL instructions both isinsta and castclass.
But the IL code for as keyword usage has only isinsta.
In the above mentioned usage, two typecast will happen where is keyword is used and only one typecast where as keyword is used.
Note: If you are using is keyword to check some condition and do not have any interest in the typecast result, then there will be only one typecast, i.e.
if (baseclassInstance is DerivedClass)
{
// do something based on the condition check.
}
is and as keywords will be used based on the necessity.

The is keyword checks whether the value on its left side is an instance of the type on the right side. For example:
if(obj is string)
{
...
}
Note that in this case you'll have to use an extra explicit cast to get obj as string.
The as keyword is used to cast nullable types. If the specified value is not an instance of the specified type, null is returned. For example:
string str = obj as string;
if(str != null)
{
...
}

is OPERATOR
The is operator in C# is used to check the object type and it returns a bool value: true if the object is the same type and false if not.
or also The “is” operator is used to check whether the run-time type of an object is compatible with a given type or not.
For null objects, it returns false
e.g
if(obj is AnimalObject)
{
//Then Work
}
as OPERATOR
The as operator does the same job of is operator but the difference is instead of bool, it returns the object if they are compatible to that type, else it returns null.In otherwords, The ‘as‘ operator is used to perform conversions between compatible types.
e.g
Type obj = Object as Type;
Advantages of as over is
In case of is operator, to type cast, we need to do two steps:
Check the Type using is
If it’s true then Type cast
Actually this affects the performance since each and every time the CLR will go through the inheritance hierarchy, checking each base type against the specified type.
To avoid this, use as, it will do it in one step. Only for checking the type should we use the is operator.

I would say: read MSDN online, but here it is:
The is operator checks whether an object is compatible with a given type, and the result of the evaluation is a Boolean: true or false.
The as operator will never throw an exception.

Is operator , a cast, returns true if it succeeds. It returns false if the cast fails. With it, you cannot capture the converted variable. This operator is most useful when checking types in if-statements and expressions.The is-cast is only ideal if the resulting variable will not be needed for further use
As is a cast. With it, we gain performance and avoid exceptions when a cast is invalid. Null is returned when the cast is impossible. For reference types, the as-cast is recommended. It is both fast and safe.We can test the resulting variable against null and then use it. This eliminates extra casts

is operator checks whether the object is compatible with the given
type the result based upon true or false.
as is used to cast one type to another type and on conversion
failure results null except then raising exception.
well see link for better understanding with examples https://blogs.msdn.microsoft.com/prakasht/2013/04/23/difference-between-direct-casting-is-and-as-operator-in-c/

The As operator is similar to a cast, but returns null instead of an exception if it fails.
And the Is operator is used to check if one object is compatible with a certain type. It's usually used in If statements.

is: The is operator is used to check whether the run-time type of an object is compatible with a given type
as: The as operator is used to perform conversions between compatible types.
object s = "this is a test";
string str=string.Empty;
if( s is string)
str = s as string;

MyClass myObject = (MyClass) obj;
vs
MyClass myObject = obj as MyClass;
The second will return null if obj isn't a MyClass, rather than throw a class cast exception.
is will only return true or false

Both IS and AS are used for Safe Type Casting
IS Keyword-->
checks whether the type of an given object is compatible with the new object type. It Never Throws an exception. This is a Boolean type..returns either true or false
`student stud = new student(){}
if(stud is student){} // It returns true // let say boys as derived class
if(stud is boys){}// It returns false since stud is not boys type
//this returns true when,
student stud = new boys() // this return true for both if conditions.`
AS Keyword:
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.
`student stud = new student(){}
// let say boys as derived class
boys boy = stud as boys;//this returns null since we cant convert stud type from base class to derived class
student stud = new boys()
boys boy = stud as boys;// this returns not null since the obj is pointing to derived class`

Both operator are used for safe type casting.
AS Operator :
The AS operator also checks whether the type of a given object is compatible with the new object type. This keyword will check whether the type of a given object is compatible with the new object type. If it's not compatible with the new one then it will return NULL.
IS Operator:
This Operator checks whether the type of an object is compatible with the new object. If it's compatible it returns true otherwise false.

Related

"is" keyword when casting and then check null

I'm new to C#, just a question on the use of "is" keyword.
I saw one of my textbook was using:
if (obj is Person && obj != null)
{
...
}
but is obj != null redundant?
The is keyword evaluates type compatibility at runtime. It determines whether an object instance or the result of an expression can be converted to a specified type.
if (obj is Person) {
// Do something if obj is a Person.
}
You can also check for null.
So don't perform a null check.
var obj = new object();
Console.WriteLine(obj is null);
In this case else part will execute.
object obj = null;
if(obj is CustomData)
{
Console.WriteLine("Match");
}
else
{
Console.Write("Null");
}
Although useful, I would really advise not using it and instead, use as. The as keyword is a defensive cast, which means that a cast will be attempted and if the object is not able to be cast to the supplied type null is returned instead.
The reason I’d advise against using it because it will actually cause you to perform 2 casts – one to check if the object is of the type and then a second to actually capture the casted value.
Refer This
Refer This
I think very simply explain to you here
Person obj = new Person();
if (obj is Person && obj!=null){};
Is check the type and it will return a bool that is true or false. Is an operator never throw an error. Is refer metadata find out the type an object is found then it will return true otherwise return false.
Person obj = null;
if (obj is Person){//return always false}
if you try above code is return always return false.
obj!=null
!= is inequality operator if its operands are not equal it will return true otherwise false.
refer documentation "Is"
Equality Operator

How to Cast A Variable Using Generic Type Parameter and 'as' Operator

I have the following generic static class which is being used in a Fluent API. It takes an input parameter and returns a wrapper class containing the parameter cast to the generic type.:
public static Foo<TOut> InputAs<TOut>(object parameter) {
var castParameter = parameter as TOut;
if(castParameter == null) {
throw new Exception("Invalid cast");
}
return new Foo<TOut>(castParameter);
}
The problem is that the castParameter == null check always returns null. What would be the correct way to cast the object using the TOut generic parameter as the new type?
Well, if parameter as TOut returns null, then the runtime type of parameter isn't TOut.
Don't forget that operator resolution is done at compile-time, so if you have cast operators defined, they will not be invoked here. If you do need that, you can use dynamic:
public static Foo<TOut> InputAs<TOut>(dynamic parameter)
{
return new Foo<TOut>((TOut)parameter);
}
This will allow runtime operator resolution, and will call your cast operator if one is available. For example, it will allow you to pass long, while expecting int.
However, you probably want to find a different way of what you're trying to do; dynamic can be very useful, but it can also make debugging quite a bit harder, and you lose almost all compile-time warnings and errors that can help you identify problems before they happen.

Generic method returns nullReferenceException

I have this Generic Method that always returns a nullReferenceException. I've taken all the unnecessary code out, and it still give me the exception.
public T RetrieveInformationFromApi<T>(int Id) where T : IMovie
{
T result = default(T);
result.Title = "test";
}
The method can be called with three different classes that all have the attribute Title and the all implement the interface IMovie but the method still give me an exception. What am i doing wrong?
You should add a constructor constraint on you T parameter so you can create a new instance.
public T RetrieveInformationFromApi<T>(int Id) where T : IMovie, new()
{
T result = new T();
result.Title = "test";
}
You're using default which returns null for reference types (and I'm guessing you're using a reference type.
From MSDN:
Given a variable t of a parameterized type T, the statement t = null is only valid if T is a reference type and t = 0 will only work for numeric value types but not for structs. The solution is to use the default keyword, which will return null for reference types and zero for numeric value types.
I'm not sure what you're trying to achieve but this way you will always get that exception for reference types.
When the T is a reference type (class), the default (T) returns null, as it is the default value of all reference types.
Then obviously trying to access its property results in NullReferenceException

Why can I use (string) but not "as string" in Linq to XML queries?

So I've been diving into Linq to XML for the first time (I know, I'm behind on the times) and so far it's pretty cool. However, I came across this very confusing behavior.
I'm parsing the common .resx format. In it, you have data tags that have a value and an optional comment. Here is the code I tried at first:
var items = from str in doc.Root.Descendants("data")
select new ResourceValue
{
Name = str.Attribute("name").Value,
Value = str.Element("value").Value,
Comment=str.Element("comment").Value
};
Of course, where I get the .value of the comment element though, it throws a null reference exception.. Well, let's try again. I heard you can cast XElement to a string and it'll magically work. Let's try that
var items = from str in doc.Root.Descendants("data")
select new ResourceValue
{
Name = str.Attribute("name").Value,
Value = str.Element("value").Value,
Comment=str.Element("comment") as string
};
Oooh. This time I get a compiler error.
Cannot convert type 'System.Xml.Linq.XElement' to 'string' via a
reference conversion, boxing conversion, unboxing conversion, wrapping
conversion, or null type conversion
Well, that's odd.. Let's search stackoverflow. Lo and behold, I find a snippet that suggests this instead:
var items = from str in doc.Root.Descendants("data")
select new ResourceValue
{
Name = str.Attribute("name").Value,
Value = str.Element("value").Value,
Comment=(string)str.Element("comment")
};
Whoa. That works!? But, casting null to string throws a null reference exception... doesn't it? I thought as string was exactly for this situation!?
How does this work, and why can I do an explicit cast, but not an explicit as cast?
str.Element("comment") as string
This checks if XElement is a string. But it's not true - XElement is not derived from string, so it is not a string. That's why you have error.
(string)str.Element("comment")
This is an overloaded operator, which gets Value property internally:
public static explicit operator string(XElement element)
{
if (element == null)
return null;
return element.Value;
}
It first checks if operand is null and just returns null if so. That's why you don't have exception.
BTW there is interesting thing with these explicit casting operators - none of them will throw NullReferenceException because they check element for null before accessing it's Value property. Even if element is null and you are trying to get integer, then you will have ArgumentNullException instead of NullReferenceException. And if null is acceptable value for type you are casting to (i.e. nullable types or string) then null is returned without any exceptions. That's why using these explicit casting operators is much safer than accessing Value property.
obj as string - this is an attempt to convert the object to a string, which may or may not fail (if it fails, the result is null), no exception will be thrown.
(string)obj - this is an explicit cast of obj to the type string, you are telling the compiler that obj is a string. If obj is not a string type, you will get a cast exception.
Refer this link for further insight.-
Difference between casting/conversion methods in C#

When and where to use GetType() or typeof()? [duplicate]

This question already has answers here:
What is the difference of getting Type by using GetType() and typeof()? [duplicate]
(4 answers)
Closed 5 years ago.
Why this works
if (mycontrol.GetType() == typeof(TextBox))
{}
and this do not?
Type tp = typeof(mycontrol);
But this works
Type tp = mycontrol.GetType();
I myself use is operator for checking type but my understanding fails when I use typeof() and GetType()
Where and when to use GetType() or typeof()?
typeof is an operator to obtain a type known at compile-time (or at least a generic type parameter). The operand of typeof is always the name of a type or type parameter - never an expression with a value (e.g. a variable). See the C# language specification for more details.
GetType() is a method you call on individual objects, to get the execution-time type of the object.
Note that unless you only want exactly instances of TextBox (rather than instances of subclasses) you'd usually use:
if (myControl is TextBox)
{
// Whatever
}
Or
TextBox tb = myControl as TextBox;
if (tb != null)
{
// Use tb
}
typeof is applied to a name of a type or generic type parameter known at compile time (given as identifier, not as string). GetType is called on an object at runtime. In both cases the result is an object of the type System.Type containing meta-information on a type.
Example where compile-time and run-time types are equal:
string s = "hello";
Type t1 = typeof(string);
Type t2 = s.GetType();
t1 == t2 ==> true
Example where compile-time and run-time types are different:
object obj = "hello";
Type t1 = typeof(object); // ==> object
Type t2 = obj.GetType(); // ==> string!
t1 == t2 ==> false
i.e., the compile time type (static type) of the variable obj is not the same as the runtime type of the object referenced by obj.
Testing types
If, however, you only want to know whether mycontrol is a TextBox then you can simply test
if (mycontrol is TextBox)
Note that this is not completely equivalent to
if (mycontrol.GetType() == typeof(TextBox))
because mycontrol could have a type that is derived from TextBox. In that case the first comparison yields true and the second false! The first and easier variant is OK in most cases, since a control derived from TextBox inherits everything that TextBox has, probably adds more to it and is therefore assignment compatible to TextBox.
public class MySpecializedTextBox : TextBox
{
}
MySpecializedTextBox specialized = new MySpecializedTextBox();
if (specialized is TextBox) ==> true
if (specialized.GetType() == typeof(TextBox)) ==> false
Casting
If you have the following test followed by a cast and T is nullable ...
if (obj is T) {
T x = (T)obj; // The casting tests, whether obj is T again!
...
}
... you can change it to ...
T x = obj as T;
if (x != null) {
...
}
Testing whether a value is of a given type and casting (which involves this same test again) can both be time consuming for long inheritance chains. Using the as operator followed by a test for null is more performing.
Starting with C# 7.0 you can simplify the code by using pattern matching:
if (obj is T t) {
// t is a variable of type T having a non-null value.
...
}
Btw.: this works for value types as well. Very handy for testing and unboxing. Note that you cannot test for nullable value types:
if (o is int? ni) ===> does NOT compile!
This is because either the value is null or it is an int. The following code works for int? o as well as for object o = new Nullable<int>(x);:
if (o is int i) ===> OK!
I like it, because it eliminates the need to access the Nullable<T>.Value property.
typeOf is a C# keyword that is used when you have the name of the class. It is calculated at compile time and thus cannot be used on an instance, which is created at runtime. GetType is a method of the object class that can be used on an instance.
You may find it easier to use the is keyword:
if (mycontrol is TextBox)

Categories