什么时候应该在C#中使用as关键字

Dan*_*tle 20 .net c# as-operator c#-3.0

当你想在大多数时候想要改变类型时,你只想使用传统的演员.

var value = (string)dictionary[key];
Run Code Online (Sandbox Code Playgroud)

这很好,因为:

  • 它很快
  • 如果出现问题,它会抱怨(而不是给对象是空的例外)

那么使用什么是一个很好的例子as我无法真正找到或想到适合它的东西?

注意:实际上我认为有时会出现编译器阻止使用强制转换的情况as(泛型相关?).

Jon*_*eet 29

as当它对象不是你想要的类型有效时使用,如果是,你想采取不同的行动.例如,在某些伪代码中:

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

    ContainerControl container = control as ContainerControl;
    if (container != null)
    {
        ApplyToChildren(container);
    }
}
Run Code Online (Sandbox Code Playgroud)

或LINQ to Objects中的优化(很多这样的例子):

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;
}
Run Code Online (Sandbox Code Playgroud)

所以使用as就像is一个演员.根据上面的例子,它几乎总是在之后使用无效检查.

  • 从语义上讲,“as is like an is + acast”。当然是正确的,有趣的是,从 IL 来看,情况并非如此(我确信您知道,但并非所有阅读您答案的人都知道)http://blogs.msdn.com/b/ericlippert/archive/2010/09/16 /is-is-as-or-is-as-is.aspx (2认同)

Sam*_*ich 16

每当你需要安全施放对象时,无异常使用as:

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

MyType a = myObj as MyType; // return null if type wrong
Run Code Online (Sandbox Code Playgroud)

  • 是的,我回答说:_当你需要安全施放物体时无例外_ (2认同)

vc *_* 74 8

正如用于避免双重铸造逻辑,如:

if (x is MyClass)
{
  MyClass y = (MyClass)x;
}
Run Code Online (Sandbox Code Playgroud)

运用

MyClass y = x as MyClass;
if (y == null)
{
}
Run Code Online (Sandbox Code Playgroud)

为案例#1生成的FYI,IL:

  // if (x is MyClass)
  IL_0008:  isinst     MyClass
  IL_000d:  ldnull
  IL_000e:  cgt.un
  IL_0010:  ldc.i4.0
  IL_0011:  ceq
  IL_0013:  stloc.2
  IL_0014:  ldloc.2
  IL_0015:  brtrue.s   IL_0020
  IL_0017:  nop
  // MyClass y = (MyClass)x;
  IL_0018:  ldloc.0
  IL_0019:  castclass  MyClass
  IL_001e:  stloc.1
Run Code Online (Sandbox Code Playgroud)

对于案例#2:

  // MyClass y = x as MyClass;
  IL_0008:  isinst     MyClass
  IL_000d:  stloc.1
  // if (y == null)
  IL_000e:  ldloc.1
  IL_000f:  ldnull
  IL_0010:  ceq
  IL_0012:  stloc.2
  IL_0013:  ldloc.2
  IL_0014:  brtrue.s   IL_0018
Run Code Online (Sandbox Code Playgroud)


Ros*_*oss 5

使用as将不会引发强制转换异常,而仅null在强制转换失败时返回。