4 回答
TA贡献2021条经验 获得超8个赞
as
if (randomObject is TargetType tt){
// Use tt here}ttifis
别这么做: // 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 关注
- 793 浏览
添加回答
举报
