我应该使用(ObjectType)还是';作为对象类型';用c#铸造时?
可能重复:我应该使用(ObjectType)还是';作为对象类型';用c#铸造时?,c#,casting,C#,Casting,可能重复: 比如说,我有一个名为MyObjectType的类,我想将事件的sender参数转换为这种类型。我通常会简单地这样做: MyObjectType senderAsMyType = (MyObjectType) sender; 我最近意识到也可以这样做: MyObjectType senderAsMyType = sender as MyObjectType; 哪种方式最有效?因此,我可以使我的代码保持一致,并在整个过程中使用其中一种方法。或者他们都有赞成和反对的意见?如果有的话,
比如说,我有一个名为MyObjectType的类,我想将事件的sender参数转换为这种类型。我通常会简单地这样做:
MyObjectType senderAsMyType = (MyObjectType) sender;
我最近意识到也可以这样做:
MyObjectType senderAsMyType = sender as MyObjectType;
哪种方式最有效?因此,我可以使我的代码保持一致,并在整个过程中使用其中一种方法。或者他们都有赞成和反对的意见?如果有的话,请有人告诉我
再次感谢,如果您希望避免任何
无效的例外情况,请使用
MyObjectType senderAsMyType = sender as MyObjectType;
否则使用
MyObjectType senderAsMyType = (MyObjectType)sender;
如果InvalidCastException
代表应用程序中真正的异常情况
至于表现,我认为你不会发现这两种不同类型的演员之间有明显的区别。但我很感兴趣,因此我使用并获得了证实我怀疑的结果:
测试:
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
输出:
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
我认为这个答案将有助于
基本区别:如果sender
不是MyObjectType
的实例或其子类之一,则第一个示例(直接转换)抛出异常;第二个(as运算符)返回null
它们都不是明显的好或坏;根据你目前面临的情况,你应该使用其中一种。如果sender
不是MyObjectType
您想做什么?可能,在本例中,因为它是一个事件处理程序,所以抛出异常非常好…您应该尽可能使用(MyObjectType)
,因为如果强制转换失败,您将立即得到异常。使用as
以后,您可能会在任何地方出现NullRef异常。
只有在处理完失败的强制转换后,才使用as
。他们做的事情略有不同。这取决于你想要什么
// Will throw an exception if the cast cannot be made
MyObjectType foo = (MyObjectType)bar;
或
你用哪个取决于你?如果您预计强制转换可能会频繁失败(您对此很满意),请选择作为
,然后测试null,如果您预计强制转换永远不会失败,请选择(键入)
请记住,如果引用可以是null
,并且您也需要知道这一点,那么在播放之前测试null
。不要太担心效率,最好根据语义做出决定。一种方法是否比另一种方法更有效在很大程度上取决于具体情况,以及您期望它失败多少次
直接强制转换“(ObjectType)”可能会失败,并将抛出InvalidCastException
“as”不会因异常而失败,但如果强制转换不起作用,则会返回null对象
如果强制转换确实有效,只需执行强制转换即可。这样,如果事情出了问题,你将得到例外,希望能够解决问题
如果您不确定对象类型,那么使用“as”并检查null可能会很有用
MyObjectType senderAsMyType = (MyObjectType) sender;
MyObjectType senderAsMyType = sender as MyObjectType;
if(senderAsMyType != null)
{
senderAsMyType.MyMethod()
}
如果无法将发送方强制转换为MyObjectType
,这将抛出一个InvalidCastException
MyObjectType senderAsMyType = sender as MyObjectType;
如果无法将发件人强制转换为MyObject
,则senderAsMyType
将为null
。此方法不能与值类型一起使用
我相信后者的速度稍微快一点,但差别实际上是微不足道的。这取决于你对目标的期望。如果对象应为该类型,并且您需要访问该对象成员,请使用:
MyObjectType senderAsMyType = (MyObjectType) sender;
如前所述,如果无效,则会为您抛出一个InvalidCastException
如果它可能是那种类型,并且您只想在它是的情况下采取行动,请使用“as”,并检查null
MyObjectType senderAsMyType = (MyObjectType) sender;
MyObjectType senderAsMyType = sender as MyObjectType;
if(senderAsMyType != null)
{
senderAsMyType.MyMethod()
}
但是,如果只检查类型,而不需要对象,请使用“is”运算符,因为这将是最便宜的资源
if(sender is MyObjectType)
//do something
从最佳实践的角度来看,如果您希望得到不同类型的对象,并且您的代码可以处理它们,那么您应该使用作为
关键字,例如
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);
这样不仅更快,而且不会隐藏错误。Aah抱歉,我搜索时找不到答案。Thanks我认为速度是非常主观的,并且会受到你期望的铸造失败百分比的影响。一个没有人提到的重要一点是铸造和“as”不做相同的事情。例如,如果您有一个用户定义的从Foo到Bar的显式转换,那么“(Bar)Foo”调用转换方法,但“Foo as Bar”不调用。确保你选择了真正符合你要求的选项。使它正确,然后把它弄清楚,然后才考虑使它更快。