简体   繁体   English

为什么使用TryCast而不是DirectCast?

[英]Why use TryCast instead of DirectCast?

When I am trying to cast Object obj to Type T , if it can not be cast then there is something wrong. 当我试图将Object obj为Type T ,如果无法Object obj转换,那么就会出现问题。

And after I cast the object I will be looking for working with the cast object. 在我投射对象之后,我将寻找使用投射对象。

Rather I will be expecting to get an exception at the place where I will be casting it than say where I will be using that object. 相反,我会期望在我将要投射它的地方得到一个例外,而不是说我将使用该对象。

In this sense, is it better to use DirectCast instead of TryCast ? 从这个意义上讲,使用DirectCast而不是TryCast是否更好? Or am I missing some other significance of using TryCast ? 或者我错过了使用TryCast其他一些意义?

(For C# developers, TryCast is similar to "as" and DirectCast is the equivalent of normal casting. As Mike pointed out in the comments, "as" works for nullable value types, but TryCast doesn't.) (对于C#开发人员, TryCast类似于“as”, DirectCast相当于普通的转换。正如Mike在评论中指出的那样,“as”适用于可空值类型,但TryCast不适用。)

If the value really should be a T , then DirectCast is indeed the right way to go - it fails fast, with an appropriate error. 如果该值确实应该是T ,那么DirectCast确实是正确的方法 - 它会快速失败并出现相应的错误。

TryCast is appropriate when it's legitimate for the target to be the "wrong" type. 当目标成为“错误”类型合法时, TryCast是合适的。 For instance, to get all the Button controls in a container, you could go through the control collection and try to cast each to Button. 例如,要获取容器中的所有Button控件,您可以浏览控件集合并尝试将每个控件转换为Button。 If it works, you do something with it - if it doesn't, you move on. 如果它有效,你会用它做一些事情 - 如果没有,你继续前进。 (With LINQ you can just use OfType for this purpose, but you see what I mean...) (使用LINQ,你可以使用OfType来达到这个目的,但你明白我的意思......)

In my experience direct casting is appropriate more often than TryCast - although with generics I find myself casting a lot less often than I used to anyway. 根据我的经验,直接投射比TryCast更合适 - 尽管使用仿制药我发现自己的投射比以往任何时候都少。

The only difference between the two is that, a TryCast will return a null if it fails, while a DirectCast will throw an exception. 两者之间的唯一区别是,如果TryCast失败,它将返回null,而DirectCast将抛出异常。

These has implications on how you can handle your program. 这些对您如何处理程序有影响。 Personally I prefer not having to throw an exception if the possibility of an improper cast (eg, text input boxes for user input being cast into numeric types) is pretty high. 就个人而言,如果不正确演员的可能性(例如,用户输入的文本输入框被转换为数字类型)非常高,我更喜欢不必抛出异常。

I think the others have mentioned the times when you should and shouldn't perform "safe casting" (where you ensure that the cast can succeed before risking an exception). 我认为其他人已经提到了你应该而且不应该执行“安全施法”的时间(在你冒着异常的情况下确保施法可以成功的地方)。 If your program does need to perform safe casting then the TryCast method saves both you and the program some work. 如果您的程序确实需要执行安全转换,那么TryCast方法会为您和程序保存一些工作。

I wasn't aware of the TryCast() function until today, and I feel like a fool for using the 'bad' method of safely casting. 直到今天我还没有意识到TryCast()函数,我觉得使用安全铸造的“坏”方法是个傻瓜。

If you did not know about the TryCast() function then you might end up with something like this: 如果您不了解TryCast()函数,那么您最终可能会遇到以下情况:

'' wasteful, the TypeOf and DirectCast calls are redundant
If TypeOf obj Is SomeClass Then
    someObj = DirectCast(obj, SomeClass)
    '' More code
End If

The problem is that this method actually performs two casts (technically I think they're actually type-checks). 问题是这个方法实际上执行了两次转换(技术上我认为它们实际上是类型检查)。 Using the TryCast and checking if the result is Nothing eliminates the 2nd cast and saves needless work. 使用TryCast并检查结果是否为Nothing消除了第二次演员并节省了不必要的工作。

'' efficient, only one cast is ever performed and there are no InvalidCastExceptions thrown
someObj = TryCast(obj, SomeClass)
If someObj IsNot Nothing Then
    '' More code
End If

Following this pattern lets you avoid having to handle expensive exceptions, and efficiently cast to the correct type. 遵循此模式可以避免必须处理昂贵的异常,并有效地转换为正确的类型。

If your design mandates that the object passed to you MUST be of type T, then assert (as in Debug.Assert) that the cast succeeds in debug builds and run exhaustive unit tests to prove that your implementation follows your design. 如果你的设计要求传递给你的对象必须是T类型,那么断言(如在Debug.Assert中),演员在调试版本中成功并运行详尽的单元测试以证明你的实现遵循你的设计。

With your design proven and tested, you can perfrom the direct cast knowing that it can never fail. 经过您的设计验证和测试,您可以直接演员,知道它永远不会失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM