Real use for `as` and` is`

I use as or is in C # or any language that supports the keyword.

What did you use it for?

I don’t mean how I use it, I mean, how do you really need it?

I also managed to avoid imparting no typicality to a rather large C ++ project (I was proud).

So, given that I almost never set the type, why do I need the as or is keyword?

+15
c # keyword language-features
Oct 15 '09 at 13:06
source share
14 answers

I had to write code to list all the controls hosted on an ASP.NET web page and perform certain operations on specific controls, for example. add background color to all text fields, etc.

The main advantage of as and is for me is that I can confidently check whether a variable has a given type using is without any exceptions. Once I'm sure that this is a specific type, I can safely and easily convert it to the type needed with as .

What I basically did (simplified!) Is

 foreach(Control c in form.Controls) { if(c is Textbox) HandleTextbox(c as Textbox); if(c is Listbox) HandleListbox(c as Listbox); } 

etc. Without as and is it would be much merciless, IMHO.

Basically, you probably need or can make good use of as and is if you are dealing with polymorphism - if you have lists of things that can be of any number of types, for example, page controls in my example. If you do not have or use polymorphism a lot, you are unlikely to come across the need for these operators.

Mark

+34
Oct 15 '09 at 13:11
source share

I use “how” as a convenient shortcut in event handlers to return a dispatch object when I cannot know during sender development.

 protected void SomeButtonInAGridView_Click(object sender, EventArgs e) { Button clickedButton = sender as Button; } 
+16
Oct. 15 '09 at 13:10
source share

Here is one that appears a lot:

 class Foo { public override bool Equals(object obj) { // The more specific function needs to do null checking anyway. return Equals(obj as Foo); } public bool Equals(Foo obj) { // do some comparison here. } } 
+10
Oct. 15 '09 at 13:10
source share

Intriguing question. In fact, I use them all the time. is convenient to find out if an object has a certain type, I sometimes use it in generics or in loops through objects that have different types. It is also priceless with reflection.

Another, as finds many other uses. It is often much safer to use a regular tide: when it fails, it returns null instead of an exception. I also find it with a clearer syntax and easier to use, check the return value for null, and then add an exception block.

Basically, I want to say, I prefer this:

 protected void GeneralEventHandler(object sender, EventArgs e) { Button btn = sender as Button; if(btn != null) // click came from a button! // do something else // other cases } 

and this:

 protected void GeneralEventHandler(object sender, EventArgs e) { if(sender is Button) // click came from a button! // do something else // other cases } 

in contrast to this:

 protected void GeneralEventHandler(object sender, EventArgs e) { try { Button btn = (Button) sender; // if we get this far, it a button } catch(InvalidCastException ice) { // click did not come from a button! Handle other cases } } 

Of course, this is just an example, but when I can avoid try / catch, I will. It also provides more opportunities for real exceptions.

+8
Oct. 15 '09 at 13:09
source share

I use it to cleanly retrieve data from a DataReader , which may be DBNull .

 int? personHeight = dr["Height"] as int?; 

or

 int personHeight = dr["Height"] as int? ?? 0; 
+7
Oct. 15 '09 at 14:50
source share

Here is a post from Eric Lippert describing how “how” is used in C #:

http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx

I use all the time. When I need to undo a serialized object from the session cache, I use it to determine if the serialized object exists and the desired type. I can avoid the program throwing an error using the as operator and checking for null. If it is zero, I know that something is missing, and I can recreate the object and insert it back into the cache the next time I need it.

You can accomplish the same result with the translation operator, but this adds the overhead of the exception, especially if you know that the serialized object will not be part of the time.

+3
Oct 15 '09 at 13:10
source share

C # offers a way to use using the is and as operator. The operator-operator checks whether the object is compatible with this type, and the result of the evaluation is logical: true or false. The operator will never throw an exception. The following code demonstrates:

 System.Object o = new System.Object(); System.Boolean b1 = (o is System.Object); // b1 is true. System.Boolean b2 = (o is Employee); // b2 is false. 

If the object reference is zero, the is operator always returns false, because there is no object available to check its type.

The is statement is usually used as follows:

 if (o is Employee) { Employee e = (Employee) o; // Use e within the 'if' statement. } 

In this code, the CLR actually checks the type of objects twice: the operator first checks to see if it is compatible with the Employee type. If this is the case, then inside the if statement the CLR again checks that o refers to the Employee when performing the throw.

C # offers a way to simplify this code and improve its performance by providing an operator:

 Employee e = o as Employee; if (e != null) { // Use e within the 'if' statement. } 

In this code, the CLR checks to see if o is compatible with the Employee type, and if so, returns a non-zero pointer to the same object. If o is not compatible with the Employee type, then the as operator returns null.

+2
Oct. 15 '09 at 13:20
source share

If you have ever developed a project that offers a plugin interface, then as and is will quickly become your good friends VERY .

+2
Oct. 15 '09 at 14:45
source share

Here is another use case to enter Dr. Caligari’s office; -)

You can bind the as operator, as in:

 x = obj as Label as Control; 

Why are you doing this? If you want to null if it is not a label, but you want to treat them all as Control. Just casting the text box and shortcut directly into the control will succeed for both, now it will be null for unwanted types of controls. This is a quick access method that you will not often need, but sometimes convenient.

An alternative use for this is when you need ToString() for an object, but only when it is of the correct type, otherwise you want to use the default string. This is a scenario that I encounter very often, especially. with POCOs. Since ToString() is virtual, this works:

 // assume SomeClass has overridden ToString() // return "none" if item is not of type SomeClass or if it is null to begin with string itemText = (item as SomeClass as Object ?? "none").ToString(); 
+2
Oct. 15 '09 at 15:11
source share

C-style assignments (e.g. (Foo)bar ) will throw an InvalidCastException if a reset occurs. as , on the other hand, will give null (see this ). The is operator is simply used to check whether the runtime type of a given instance is compatible with the provided type (see this ).

is widely used in the .NET System.ComponentModel namespace. More specifically, the TypeConverter API relies heavily on the is operator to determine how to convert from one type to another.

+1
Oct. 15 '09 at 13:09
source share

I used both keywords extensively in a WinForms application, where there is a graphical interface for editing an invoice, each line in a ListView can contain different types of elements (i.e. it can be a position or description, or ...). All the items placed in the ListView were obtained from the ListViewItem , so later, when I went to implement things like editing the selected item, I had to check what type of item was selected (using is ) to show the corresponding graphical editing interface .

+1
Oct. 15 '09 at 13:26
source share

Custom TypeConverters comes to mind first.

 public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { if (value is string) { return GetEnumValue(myVal, (string)value); } if (value is Enum) { return GetEnumDescription((Enum)value); } return base.ConvertFrom(context, culture, value); } 



The second is the case when I have a shadow of an object (for tracking changes) that inherits from the base class

 class BaseClass { BaseClass _shadow; } protected override void UpdateShadow() { ThisClass shadow = _shadow as ThisClass; //... } 
+1
Oct 16 '09 at 9:56
source share

If you really do not need to do casting, then I most likely will not use them for these operators. However, in my experience, .NET programming requires a lot of castings, especially when working with delegates, where the arguments are provided as an “object”. I think the introduction of generics has helped reduce the need for casting, but this is certainly something that I use quite often. I could "do it wrong", but it was only my experience.

So, if you are going to do casting, I really like the 'is' operator to improve code reading. I'd rather look at

 if(foo is SomeType) {...} 

then

 if(foo.GetType() == typeof(SomeType)) {...} 
0
Oct. 15 '09 at 15:17
source share

marc_s answer is a bit corrupted, I see this code all the time, so I want to emphasize the importance of the difference between these operators. is is a logical test to determine if an object can be assigned to a particular type. as checks if an object is assigned to a particular type, and if it is, it returns this object as this type; if not, it returns null. marc_s answer really does it

 foreach(Control c in form.Controls) { if(c is Textbox) HandleTextbox(c is Textbox ? (Textbox)c : null); if(c is Listbox) HandleListbox(c is Listbox ? (Listbox)c : null); } 

You cannot use is with as . When you use as , just replace it with the expression above, this is equivalent. Use is only with live translators () or as . It is best to write this example.

 foreach(Control c in form.Controls) { if(c is Textbox) HandleTextbox((Textbox)c); //c is always guaranteed to be a Textbox here because of is if(c is Listbox) HandleListbox((Listbox)c); //c is always guaranteed to be a Listbox here because of is } 

Or if you really like as

 foreach(Control c in form.Controls) { var textBox = c as Textbox; if(textBox != null) { HandleTextbox(textBox); continue; } var listBox = c as ListBox if(listBox != null) HandleListbox(listBox); } 

The real example that I come across all the time is getting objects from the storage area that return only an object of type. Caching is a great example.

 Person p; if (Cache[key] is Person) p = (Person)Cache[key]; else p = new Person(); 

I use as much less in real code because it really only works for reference types. Consider the following code

 int x = o as int; if (x != null) ??? 

as fails because int cannot be null. is working fine though

 int x; if (o is int) x = (int)o; 

I am sure that there is a certain difference in speed between these operators, but for a real application the difference is not significant.

0
Nov 04 '09 at 12:22
source share



All Articles