4 回答
TA贡献2021条经验 获得超8个赞
as
if (randomObject is TargetType tt){ // Use tt here}
tt
if
is
别这么做: // Bad code - checks type twice for no reasonif (randomObject is TargetType){ TargetType foo = (TargetType) randomObject; // Do something with foo}
这不仅是检查两次,而且可能是检查不同的东西,如果 randomObject
是字段而不是局部变量。如果另一个线程更改 randomObject
在两者之间。 如果 randomObject
真的 应是.的一个实例 TargetType
也就是说,如果不是,这意味着有一个错误,那么转换是正确的解决方案。这会立即引发异常,这意味着在不正确的假设下不会做更多的工作,并且异常正确地显示了错误的类型。 // This will throw an exception if randomObject is non-null and// refers to an object of an incompatible type. The cast is // the best code if that's the behaviour you want.TargetType convertedRandomObject = (TargetType) randomObject;
如果 randomObject
强权是.的一个实例 TargetType
和 TargetType
是引用类型,然后使用如下代码: TargetType convertedRandomObject = randomObject as TargetType;if (convertedRandomObject != null){ // Do stuff with convertedRandomObject}
如果 randomObject
强权是.的一个实例 TargetType
和 TargetType
是一个值类型,那么我们就不能使用 as
带着 TargetType
本身,但我们可以使用一个可空类型: TargetType? convertedRandomObject = randomObject as TargetType?;if (convertedRandomObject != null){ // Do stuff with convertedRandomObject.Value}
(注:目前这是 实际上比is+强制转换慢 ..我认为它更优雅、更连贯,但我们开始了。) 如果你真的不需要转换值,但你只需要知道它是否 是一个TargetType的实例,然后是 is
接线员是你的朋友。在这种情况下,TargetType是引用类型还是值类型并不重要。 可能还有其他涉及泛型的情况 is
是有用的(因为您可能不知道T是否是引用类型,因此不能用作引用类型),但它们相对比较模糊。 我几乎肯定用过 is
对于以前的值类型情况,没有考虑使用可空类型和 as
共:)
using System;using System.Diagnostics;using System.Linq;class Test{ const int Size = 30000000; static void Main() { object[] values = new object[Size]; for (int i = 0; i < Size - 2; i += 3) { values[i] = null; values[i + 1] = "x"; values[i + 2] = new object(); } FindLengthWithIsAndCast(values); FindLengthWithIsAndAs(values); FindLengthWithAsAndNullCheck(values); } static void FindLengthWithIsAndCast(object[] values) { Stopwatch sw = Stopwatch.StartNew(); int len = 0; foreach (object o in values) { if (o is string) { string a = (string) o; len += a.Length; } } sw.Stop(); Console.WriteLine("Is and Cast: {0} : {1}", len, (long)sw.ElapsedMilliseconds); } static void FindLengthWithIsAndAs(object[] values) { Stopwatch sw = Stopwatch.StartNew(); int len = 0; foreach (object o in values) { if (o is string) { string a = o as string; len += a.Length; } } sw.Stop(); Console.WriteLine("Is and As: {0} : {1}", len, (long)sw.ElapsedMilliseconds); } static void FindLengthWithAsAndNullCheck(object[] values) { Stopwatch sw = Stopwatch.StartNew(); int len = 0; foreach (object o in values) { string a = o as string; if (a != null) { len += a.Length; } } sw.Stop(); Console.WriteLine("As and null check: {0} : {1}", len, (long)sw.ElapsedMilliseconds); }}
他们之间没有明显的差别。(事实上,在某些情况下,as-plus-null检查是肯定的。 是
慢点。上面的代码实际上使类型检查变得容易了,因为它是针对一个密封类的;如果您正在检查一个接口,那么余额会稍微倾向于as-plus-null检查。) 他们都是 疯狂
快地。这很简单 不会
成为您代码中的瓶颈,除非您真的不打算这样做 什么都行
之后的值。
int value;if (int.TryParse(text, out value)){ value = int.Parse(text); // Use value}
- 4 回答
- 0 关注
- 635 浏览
添加回答
举报