A real use for `as` and `is`

2019-04-19 00:39发布

I have -never- used as or is in C# or any language that supports the keyword.

What have you used it for?

I dont mean how do i use it i mean how have you actually need it?

I also got away with doing no typecasting in a fairly large c++ project (i was proud).

So considering i almost never typecast why do i need the keyword as or is?

14条回答
手持菜刀,她持情操
2楼-- · 2019-04-19 01:04

I use it for cleanly getting data from a DataReader that might be DBNull.

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

or

int personHeight = dr["Height"] as int? ?? 0;
查看更多
smile是对你的礼貌
3楼-- · 2019-04-19 01:08

Custom TypeConverters comes first to mind.

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);
        }

Second comes from a case where I have a shadow of an object (for tracking changes) which is inherited from a base class

class BaseClass
{
    BaseClass _shadow;
}

protected override void UpdateShadow()
{
    ThisClass shadow = _shadow as ThisClass;
      //...
}
查看更多
成全新的幸福
4楼-- · 2019-04-19 01:10

If you ever develop on a project that offers a plugin interface then as and is will quickly become your VERY best friends.

查看更多
叼着烟拽天下
5楼-- · 2019-04-19 01:12

Here is a post from Eric Lippert describing how "as" 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 as all the time. When i have to pull back a serialized object from session cache, I use as to determine if the serialized object is there and of the right type. I can avoid the program throwing an error, using the as operator and checking for null. If it's null, I know something is missing, and I can recreate the object and push it back into cache for the next time I need it.

You could accomplish the same result using the cast operator, but that adds the overhead of an exception, especially when you know that the serialized object isn't going to be there part of the time.

查看更多
女痞
6楼-- · 2019-04-19 01:13

marc_s's answer is a little flawed, I see this code all the time so I want to emphasize the importance of the difference between these operators. is is a boolean test to determine if an object is assignable to a certain type. as checks to see if an object is assignable to a certain type and if it is, it returns that object as that type, if not, it returns null. marc_s's answer is really doing this

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);
}

It is redundant to use is with as. When ever you use as just replace it with the expression above, it is equivalent. Use is with direct casts () or as only by itself. A better way to write that example would be.

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);
}

A real world example that I run into all the time is getting objects from a storage area that only return type object. 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 an int can't be null. is works fine though

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

I am sure there is also some speed difference between these operators, but for a real application the difference is negligible.

查看更多
▲ chillily
7楼-- · 2019-04-19 01:15

C# offer way to cast using the is and as operator. 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 is 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 null, the is operator always returns false because there is no object available to check its type.

The is operator is typically used as follows:

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

In this code, the CLR is actually checking the object’s type twice: the is operator first checks to see if o is compatible with the Employee type. If it is, then inside the if statement, the CLR again verifies that o refers to an Employee when performing the cast.

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

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

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

查看更多
登录 后发表回答