比如说我有一个名为MyObjectType的类,我想将事件的sender参数转换为此类型。我通常会这样做:
MyObjectType senderAsMyType = (MyObjectType) sender;
我最近意识到它也可以这样做:
MyObjectType senderAsMyType = sender as MyObjectType;
哪种方式效率最高?这样我就可以使代码保持一致并始终使用其中一种方法。或者他们都有职业和缺点?如果是这样,请有人告诉我他们。
再次感谢,
答案 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)
我认为这个答案会有所帮助......
答案 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);
这种方式不仅更快,而且不会隐藏错误。