Possible Duplicate:
Casting: (NewType) vs. Object as NewType可能重复:转换:(NewType)与Object作为NewType
Say for example I have a class called MyObjectType and I want to convert the sender parameter of an event to this type. I would usually go about it by simply doing this:
比方说,我有一个名为MyObjectType的类,我想将事件的sender参数转换为此类型。我通常只需这样做就可以了:
MyObjectType senderAsMyType = (MyObjectType) sender;
I've recently realised that it can also be done like this:
我最近意识到它也可以这样做:
MyObjectType senderAsMyType = sender as MyObjectType;
Which way is most efficient? So that I can make my code consistent and use one of the ways throughout. Or do they both have pro's and cons? If so please could someone inform me of them.
哪种方式最有效?这样我就可以使代码保持一致并始终使用其中一种方法。或者他们都有职业和缺点?如果是这样,请有人告诉我他们。
Thanks again,
9 个解决方案
#1
If you wish to avoid any InvalidCastExceptions
use
如果您希望避免使用任何InvalidCastExceptions
MyObjectType senderAsMyType = sender as MyObjectType;
otherwise use
MyObjectType senderAsMyType = (MyObjectType)sender;
if an InvalidCastException
represents a true exceptional situation in your application.
如果InvalidCastException表示应用程序中的真正异常情况。
As for performance, I would contend that you would find no discernible difference between the two different kinds of casting. I was interested though so I used Jon Skeet's BenchmarkHelper and achieved results that confirmed my suspicions:
至于表现,我认为你会发现两种不同的铸造之间没有明显的区别。我很感兴趣,所以我使用Jon Skeet的BenchmarkHelper并取得了证实我怀疑的结果:
Test:
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;
}
}
Output:
============ Casting ============
cast 30.021 1.00
asCast 30.153 1.00
#2
I think this answer will help...
我认为这个答案会有所帮助......
Casting: (NewType) vs. Object as NewType
转换:(NewType)与Object作为NewType
#3
Basic difference: if sender
is not an instance of MyObjectType
or one of its subclasses, the first example (direct cast) throws an exception; the second (as operator) returns null.
基本区别:如果sender不是MyObjectType的实例或其子类之一,则第一个示例(direct cast)会抛出异常;第二个(作为运算符)返回null。
None of them is plainly better or worse; you should use the one or the other according to the situation you are facing at the moment. If sender
is not a MyObjectType
what do you want to do? probably, in this case, since it's an event handler, throwing exception is perfectly fine...
他们中没有一个明显更好或更糟;你应该根据你目前面临的情况使用这一个。如果发件人不是MyObjectType你想做什么?可能,在这种情况下,因为它是一个事件处理程序,抛出异常是完全正常的...
#4
You should use (MyObjectType)
whenever possible, because you will get an exception right away if the cast fails. With as
you might get a NullRef-exception anywhere later.
Use as
only when you handle a failed cast right afterwards.
您应尽可能使用(MyObjectType),因为如果转换失败,您将立即获得异常。因为你可能会在以后的任何地方获得NullRef异常。仅在您之后处理失败的演员表时使用。
#5
They do slightly different things. It depends on what you want.
他们做的事略有不同。这取决于你想要什么。
// Will throw an exception if the cast cannot be made
MyObjectType foo = (MyObjectType)bar;
or
// Will return null if the cast cannot be made
MyObjectType foo = bar as MyObjectType;
Which you use is up to you? If you expect the cast to potentially fail frequently (and you are happy with that) go for as
and test for null afterwards, if you expect it never to fail go for (type)
.
您使用哪个取决于您?如果您希望演员表可能经常失败(并且您对此感到满意),那么请在之后测试为null,如果您希望它永远不会失败,请选择(类型)。
Remember, that if the reference can be null
anyway and you need to know that too, test for null
before the cast.
请记住,如果引用无论如何都可以为null,并且您也需要知道它,那么在转换之前测试null。
#6
MyObjectType senderAsMyType = (MyObjectType) sender;
This will throw an InvalidCastException
if sender cannot be cast to MyObjectType
.
如果无法将发送者强制转换为MyObjectType,则会抛出InvalidCastException。
MyObjectType senderAsMyType = sender as MyObjectType;
senderAsMyType
will be null
if sender cannot be cast to MyObject
. This method cannot be used with value types.
如果无法将发件人强制转换为MyObject,则senderAsMyType将为null。此方法不能与值类型一起使用。
I believe the latter is marginally faster, but the difference is virtually insignificant.
我相信后者稍微快一点,但差别几乎无关紧要。
#7
It depends on your expectations of your objects. If the object should be of that type, and you need to access that objects members, use:
这取决于您对对象的期望。如果对象应该是该类型,并且您需要访问该对象成员,请使用:
MyObjectType senderAsMyType = (MyObjectType) sender;
As stated before, this throws an InvalidCastException for you if it is invalid
如前所述,如果它无效,则会为您抛出InvalidCastException
If it might be of that type, and you only want to take action if it is, use 'as', and check for null
如果它可能属于那种类型,并且你只想采取行动,则使用'as',并检查是否为null
MyObjectType senderAsMyType = sender as MyObjectType;
if(senderAsMyType != null)
{
senderAsMyType.MyMethod()
}
However if you are only checking the type, but do not need the object, use the 'is' operator, as this will be cheapest resource-wise
但是,如果您只检查类型,但不需要该对象,请使用'is'运算符,因为这将是最便宜的资源方式
if(sender is MyObjectType)
//do something
#8
Don't worry too much about efficiency, it's better to make the decision based on semantics. Whether one is more efficient than the other will depend heavily on individual circumstance, and how many times you expect it to fail.
不要过分担心效率,最好根据语义做出决定。一个人是否比另一个人更有效将在很大程度上取决于个人情况,以及你期望失败多少次。
A straight cast "(ObjectType)" can fail, and will throw an InvalidCastException.
直接转换“(ObjectType)”可能会失败,并将抛出InvalidCastException。
"as" will not fail with an exception, but instead will return a null object if the cast doesn't work.
“as”不会因异常而失败,但如果转换不起作用,则返回null对象。
If the cast is definitely valid, just do the cast. That way if things go wrong you will get the exception and hopefully be able to solve the problem.
如果演员阵容绝对有效,那就进行演员表演。这样一来,如果出现问题,您将获得异常,并希望能够解决问题。
If you aren't certain of the object type, it can be useful to use "as" and just check for null
如果您不确定对象类型,使用“as”并检查null是很有用的
#9
From the best practises perspective you should use the as
keyword if you expect objects of different types and your code can handle them, e.g.
从最佳实践的角度来看,如果您希望不同类型的对象和代码可以处理它们,则应使用as关键字,例如:
public void MyFunction(MyObject obj)
{
obj.DoSomething();
SpecializedObject specialized = obj as SpecializedObject;
if(specialized!=null)
{
specialized.DoSthSpecial();
}
}
And use the normal cast when you are sure the type will be what you expect, you just need to cast it because of technical reasons:
当您确定类型将是您所期望的时,使用正常演员,您只需要因为技术原因而施放它:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject));
MyObject obj = (MyObject)xmlSerializer.Deserialize(xml);
this way its not only faster, but also doesn't hide errors.
这样它不仅速度更快,而且不会隐藏错误。
#1
If you wish to avoid any InvalidCastExceptions
use
如果您希望避免使用任何InvalidCastExceptions
MyObjectType senderAsMyType = sender as MyObjectType;
otherwise use
MyObjectType senderAsMyType = (MyObjectType)sender;
if an InvalidCastException
represents a true exceptional situation in your application.
如果InvalidCastException表示应用程序中的真正异常情况。
As for performance, I would contend that you would find no discernible difference between the two different kinds of casting. I was interested though so I used Jon Skeet's BenchmarkHelper and achieved results that confirmed my suspicions:
至于表现,我认为你会发现两种不同的铸造之间没有明显的区别。我很感兴趣,所以我使用Jon Skeet的BenchmarkHelper并取得了证实我怀疑的结果:
Test:
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;
}
}
Output:
============ Casting ============
cast 30.021 1.00
asCast 30.153 1.00
#2
I think this answer will help...
我认为这个答案会有所帮助......
Casting: (NewType) vs. Object as NewType
转换:(NewType)与Object作为NewType
#3
Basic difference: if sender
is not an instance of MyObjectType
or one of its subclasses, the first example (direct cast) throws an exception; the second (as operator) returns null.
基本区别:如果sender不是MyObjectType的实例或其子类之一,则第一个示例(direct cast)会抛出异常;第二个(作为运算符)返回null。
None of them is plainly better or worse; you should use the one or the other according to the situation you are facing at the moment. If sender
is not a MyObjectType
what do you want to do? probably, in this case, since it's an event handler, throwing exception is perfectly fine...
他们中没有一个明显更好或更糟;你应该根据你目前面临的情况使用这一个。如果发件人不是MyObjectType你想做什么?可能,在这种情况下,因为它是一个事件处理程序,抛出异常是完全正常的...
#4
You should use (MyObjectType)
whenever possible, because you will get an exception right away if the cast fails. With as
you might get a NullRef-exception anywhere later.
Use as
only when you handle a failed cast right afterwards.
您应尽可能使用(MyObjectType),因为如果转换失败,您将立即获得异常。因为你可能会在以后的任何地方获得NullRef异常。仅在您之后处理失败的演员表时使用。
#5
They do slightly different things. It depends on what you want.
他们做的事略有不同。这取决于你想要什么。
// Will throw an exception if the cast cannot be made
MyObjectType foo = (MyObjectType)bar;
or
// Will return null if the cast cannot be made
MyObjectType foo = bar as MyObjectType;
Which you use is up to you? If you expect the cast to potentially fail frequently (and you are happy with that) go for as
and test for null afterwards, if you expect it never to fail go for (type)
.
您使用哪个取决于您?如果您希望演员表可能经常失败(并且您对此感到满意),那么请在之后测试为null,如果您希望它永远不会失败,请选择(类型)。
Remember, that if the reference can be null
anyway and you need to know that too, test for null
before the cast.
请记住,如果引用无论如何都可以为null,并且您也需要知道它,那么在转换之前测试null。
#6
MyObjectType senderAsMyType = (MyObjectType) sender;
This will throw an InvalidCastException
if sender cannot be cast to MyObjectType
.
如果无法将发送者强制转换为MyObjectType,则会抛出InvalidCastException。
MyObjectType senderAsMyType = sender as MyObjectType;
senderAsMyType
will be null
if sender cannot be cast to MyObject
. This method cannot be used with value types.
如果无法将发件人强制转换为MyObject,则senderAsMyType将为null。此方法不能与值类型一起使用。
I believe the latter is marginally faster, but the difference is virtually insignificant.
我相信后者稍微快一点,但差别几乎无关紧要。
#7
It depends on your expectations of your objects. If the object should be of that type, and you need to access that objects members, use:
这取决于您对对象的期望。如果对象应该是该类型,并且您需要访问该对象成员,请使用:
MyObjectType senderAsMyType = (MyObjectType) sender;
As stated before, this throws an InvalidCastException for you if it is invalid
如前所述,如果它无效,则会为您抛出InvalidCastException
If it might be of that type, and you only want to take action if it is, use 'as', and check for null
如果它可能属于那种类型,并且你只想采取行动,则使用'as',并检查是否为null
MyObjectType senderAsMyType = sender as MyObjectType;
if(senderAsMyType != null)
{
senderAsMyType.MyMethod()
}
However if you are only checking the type, but do not need the object, use the 'is' operator, as this will be cheapest resource-wise
但是,如果您只检查类型,但不需要该对象,请使用'is'运算符,因为这将是最便宜的资源方式
if(sender is MyObjectType)
//do something
#8
Don't worry too much about efficiency, it's better to make the decision based on semantics. Whether one is more efficient than the other will depend heavily on individual circumstance, and how many times you expect it to fail.
不要过分担心效率,最好根据语义做出决定。一个人是否比另一个人更有效将在很大程度上取决于个人情况,以及你期望失败多少次。
A straight cast "(ObjectType)" can fail, and will throw an InvalidCastException.
直接转换“(ObjectType)”可能会失败,并将抛出InvalidCastException。
"as" will not fail with an exception, but instead will return a null object if the cast doesn't work.
“as”不会因异常而失败,但如果转换不起作用,则返回null对象。
If the cast is definitely valid, just do the cast. That way if things go wrong you will get the exception and hopefully be able to solve the problem.
如果演员阵容绝对有效,那就进行演员表演。这样一来,如果出现问题,您将获得异常,并希望能够解决问题。
If you aren't certain of the object type, it can be useful to use "as" and just check for null
如果您不确定对象类型,使用“as”并检查null是很有用的
#9
From the best practises perspective you should use the as
keyword if you expect objects of different types and your code can handle them, e.g.
从最佳实践的角度来看,如果您希望不同类型的对象和代码可以处理它们,则应使用as关键字,例如:
public void MyFunction(MyObject obj)
{
obj.DoSomething();
SpecializedObject specialized = obj as SpecializedObject;
if(specialized!=null)
{
specialized.DoSthSpecial();
}
}
And use the normal cast when you are sure the type will be what you expect, you just need to cast it because of technical reasons:
当您确定类型将是您所期望的时,使用正常演员,您只需要因为技术原因而施放它:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject));
MyObject obj = (MyObject)xmlSerializer.Deserialize(xml);
this way its not only faster, but also doesn't hide errors.
这样它不仅速度更快,而且不会隐藏错误。