在c#中进行转换时,我应该使用(ObjectType)还是'as ObjectType'?

时间:2009-07-28 10:48:28

标签: c# casting

  

可能重复:
  Casting: (NewType) vs. Object as NewType

比如说我有一个名为MyObjectType的类,我想将事件的sender参数转换为此类型。我通常会这样做:

MyObjectType senderAsMyType = (MyObjectType) sender;

我最近意识到它也可以这样做:

MyObjectType senderAsMyType = sender as MyObjectType;

哪种方式效率最高?这样我就可以使代码保持一致并始终使用其中一种方法。或者他们都有职业和缺点?如果是这样,请有人告诉我他们。

再次感谢,

9 个答案:

答案 0 :(得分:4)

如果您希望避免使用任何InvalidCastExceptions

MyObjectType senderAsMyType = sender as MyObjectType;

否则使用

MyObjectType senderAsMyType = (MyObjectType)sender;

如果InvalidCastException表示您的申请中存在真正异常情况。

至于表现,我认为你会发现两种不同的铸造之间没有明显区别。我 感兴趣,所以我使用Jon Skeet's BenchmarkHelper并取得了证实我怀疑的结果:

<强>测试

using System;
using BenchmarkHelper;

class Program
{
    static void Main()
    {
        Object input = "test";
        String output = "test";

        var results = TestSuite.Create("Casting", input, output)
            .Add(cast)
            .Add(asCast)
            .RunTests()
            .ScaleByBest(ScalingMode.VaryDuration);
        results.Display(ResultColumns.NameAndDuration | ResultColumns.Score,
                results.FindBest());
    }

    static String cast(Object o)
    {
        return (String)o;
    }

    static String asCast(Object o)
    {
        return o as String;
    }

}

<强>输出:

============ Casting ============
cast   30.021 1.00
asCast 30.153 1.00

答案 1 :(得分:2)

我认为这个答案会有所帮助......

Casting: (NewType) vs. Object as NewType

答案 2 :(得分:2)

基本区别:如果sender不是MyObjectType的实例或其子类之一,则第一个示例(直接强制转换)会抛出异常;第二个(作为运算符)返回null。

他们中没有一个明显好或坏;你应该根据你目前面临的情况使用这一个。如果sender不是MyObjectType你想做什么?可能,在这种情况下,因为它是一个事件处理程序,抛出异常是完全正常的......

答案 3 :(得分:0)

您应该尽可能使用(MyObjectType),因为如果演员失败,您将立即获得异常。使用as,您可能会在以后的任何地方获得NullRef异常 仅在您之后处理失败的演员表时使用as

答案 4 :(得分:0)

他们做的事略有不同。这取决于你想要什么。

// Will throw an exception if the cast cannot be made
MyObjectType foo = (MyObjectType)bar; 

// Will return null if the cast cannot be made
MyObjectType foo = bar as MyObjectType;

你使用哪个取决于你?如果您希望演员表可能经常失败(并且您对此感到满意),请转到as并在之后测试为null,如果您预计它永远不会失败,请转到(type)

请记住,如果引用无论如何都可以null,并且您也需要知道,请在演员之前测试null

答案 5 :(得分:0)

不要过于担心效率,最好根据语义做出决定。一个人是否比另一个人更有效率将在很大程度上取决于个人情况,以及你期望失败的次数。

直接转换“(ObjectType)”可能会失败,并会抛出InvalidCastException。

“as”不会因异常而失败,但如果强制转换不起作用,则返回null对象。

如果演员阵容绝对有效,那就进行演员表演。这样一来,如果出现问题,您将获得异常,并希望能够解决问题。

如果您不确定对象类型,使用“as”并检查null是有用的

答案 6 :(得分:0)

MyObjectType senderAsMyType = (MyObjectType) sender;

如果发件人无法投放到InvalidCastException,则会抛出MyObjectType

MyObjectType senderAsMyType = sender as MyObjectType;
如果发件人无法投放到senderAsMyType

null将为MyObject。此方法不能与值类型一起使用。

我认为后者的速度略快,但差异实际上微不足道。

答案 7 :(得分:0)

这取决于您对对象的期望。如果对象应该属于该类型,并且您需要访问该对象成员,请使用:

MyObjectType senderAsMyType = (MyObjectType) sender;

如前所述,如果它无效,则会为您抛出 InvalidCastException

如果可能属于该类型,并且您只想采取行动,请使用'as',并检查是否为

MyObjectType senderAsMyType = sender as MyObjectType;

if(senderAsMyType != null)
{
    senderAsMyType.MyMethod()
}

但是,如果您只检查类型,但不需要该对象,请使用'is'运算符,因为这将是最便宜的资源

if(sender is MyObjectType)
    //do something

答案 8 :(得分:0)

从最佳实践的角度来看,如果您希望不同类型的对象和代码可以处理它们,则应使用as关键字,例如。

public void MyFunction(MyObject obj)
{
  obj.DoSomething();
  SpecializedObject specialized = obj as SpecializedObject;
  if(specialized!=null)
  {
    specialized.DoSthSpecial();
  }
}

当您确定类型符合您的预期时,请使用正常演员,您只需要因为技术原因而施放它:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject));
MyObject obj = (MyObject)xmlSerializer.Deserialize(xml);

这种方式不仅更快,而且不会隐藏错误。