When should you use the as keyword in C#

2020-03-01 04:11发布

When you want to change types most of the time you just want to use the traditional cast.

var value = (string)dictionary[key];

It's good because:

  • It’s fast
  • It’ll complain if something is wrong (instead of giving object is null exceptions)

So what is a good example for the use of as I couldn't really find or think of something that suits it perfectly?

Note: Actually I think sometimes there are cases where the complier prevents the use of a cast where as works (generics related?).

7条回答
三岁会撩人
2楼-- · 2020-03-01 04:25

Using as will not throw a cast exception, but simply return null if the cast fails.

查看更多
霸刀☆藐视天下
3楼-- · 2020-03-01 04:27

The implementation of .Count() in Enumerable uses it to make Count() for collection faster

The implementation is like:

        ICollection<TSource> collection = source as ICollection<TSource>;
        if (collection != null)
        {
            return collection.Count;
        }
        ICollection collection2 = source as ICollection;
        if (collection2 != null)
        {
            return collection2.Count;
        }

That tries to cast the source to either ICollection or ICollection both have a Count property. If that fails Count() iterates the entire source. So if you are unsure about the type and need the object of the type afterwards (like in the above example) you should use as.

If you only want to test if the object is of a given type use is and if you are sure that the object is of a given type (or derives from/implements that type) then you can cast

查看更多
Rolldiameter
4楼-- · 2020-03-01 04:28

Ok Nice replies everyone, but lets get a bit practical. In your own code,ie non-vendor code the REAL power of AS keyword doesn't come to the fore.

But when dealing with vendor objects as in WPF/silverlight then the AS keyword is a real bonus. for example if I have a series of controls on a Canvas and I want to track track thelast selectedControl, but clear the tracking varaible when I click the Canvas i would do this:

private void layoutroot_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
               //clear the auto selected control
        if (this.SelectedControl != null 
            && sender is Canvas && e.OriginalSource is Canvas)
        {
            if ((sender as Canvas).Equals(( e.OriginalSource as Canvas)))
            {
                this.SelectedControl = null;
            }
        }
    }

Another reason it use AS keyoword is when your Class implements 1 or more Interfaces and you want to explicitly use only one interface:

IMySecond obj = new MyClass as IMySecond

Although not really necessary here, it will assign null to variable obj if MyClass does not implement IMySecond

查看更多
别忘想泡老子
5楼-- · 2020-03-01 04:30

Use as when it's valid for an object not to be of the type that you want, and you want to act differently if it is. For example, in somewhat pseudo-code:

foreach (Control control in foo)
{
    // Do something with every control...

    ContainerControl container = control as ContainerControl;
    if (container != null)
    {
        ApplyToChildren(container);
    }
}

Or optimization in LINQ to Objects (lots of examples like this):

public static int Count<T>(this IEnumerable<T> source)
{
    IList list = source as IList;
    if (list != null)
    {
        return list.Count;
    }
    IList<T> genericList = source as IList<T>;
    if (genericList != null)
    {
        return genericList.Count;
    }

    // Okay, we'll do things the slow way...
    int result = 0;
    using (var iterator = source.GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            result++;
        }
    }
    return result;
}

So using as is like an is + a cast. It's almost always used with a nullity check afterwards, as per the above examples.

查看更多
甜甜的少女心
6楼-- · 2020-03-01 04:33

Here is a snippet from http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

class SomeType {
    int someField;
    // The numeric suffixes on these methods are only added for reference later
    public override bool Equals1(object obj) {
        SomeType other = obj as SomeType;
        if (other == null) return false;
        return someField == other.SomeField;
    }
    public override bool Equals2(object obj) {
        if (obj == null) return false;
        // protect against an InvalidCastException
        if (!(obj is SomeType)) return false;
        SomeType other = (SomeType)obj;
        return someField == other.SomeField;
    }
}

The Equals1 method above is more efficient (and easier to read) than Equals2, although they get the same job done. While Equals1 compiles to IL that performs the type checking and cast exactly once, Equals2 compiles to do a type comparison first for the "is" operator, and then does a type comparison and cast together as part of the () operator. So using "as" in this case is actually more efficient. The fact that it is easier to read is a bonus.

In conclusion, only use the C# "as" keyword where you are expecting the cast to fail in a non-exceptional case. If you are counting on a cast to succeed and are unprepared to receive any object that would fail, you should use the () cast operator so that an appropriate and helpful exception is thrown.

查看更多
做个烂人
7楼-- · 2020-03-01 04:35

Every time when you need to safe cast object without exception use as:

MyType a = (MyType)myObj; // throws an exception if type wrong

MyType a = myObj as MyType; // return null if type wrong
查看更多
登录 后发表回答