考虑以下代码:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.ToString(); // 3
}
三种类型的施法有什么区别(好吧,第三种不是施法,但你明白了意图)。应该首选哪一种?
考虑以下代码:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.ToString(); // 3
}
三种类型的施法有什么区别(好吧,第三种不是施法,但你明白了意图)。应该首选哪一种?
当前回答
2可用于转换为派生类型。
假设a是动物:
b = a as Badger;
c = a as Cow;
if (b != null)
b.EatSnails();
else if (c != null)
c.EatGrass();
将得到最少的投喂。
其他回答
我想提请注意as操作员的以下细节:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as
注意,as运算符仅执行参考转换,可空转换和装箱转换。as运算符不能执行其他转换,例如用户定义的转换应改为使用强制转换表达式来执行。
当您使用FindControl方法时,as关键字在asp.net中很好。
Hyperlink link = this.FindControl("linkid") as Hyperlink;
if (link != null)
{
...
}
这意味着您可以对类型化变量进行操作,而不必像直接转换那样从对象转换它:
object linkObj = this.FindControl("linkid");
if (link != null)
{
Hyperlink link = (Hyperlink)linkObj;
}
这不是一件大事,但它节省了代码行和变量赋值,而且可读性更强
string s = o as string; // 2
首选,因为它避免了双重铸造的性能损失。
使用直接转换字符串s=(string)o;如果在应用程序的逻辑上下文中,字符串是唯一有效的类型。使用这种方法,您将获得InvalidCastException并实现快速失败的原则。您的逻辑将受到保护,不会进一步传递无效类型,或者如果用作运算符,将获得NullReferenceException。
如果逻辑需要几个不同的类型,则将字符串s=o转换为字符串;并检查null或use-is运算符。
C#7.0中出现了新的酷炫功能,以简化转换,并检查模式匹配:
if(o is string s)
{
// Use string variable s
}
or
switch (o)
{
case int i:
// Use int variable i
break;
case string s:
// Use string variable s
break;
}
“(string)o”将导致InvalidCastException,因为没有直接强制转换。
“o as string”将导致s为空引用,而不是引发异常。
“o.ToString()”本身并不是任何类型的强制转换,它是一个由对象实现的方法,因此以某种方式由.net中的每个类实现,这些类对它所调用的类的实例“做一些事情”并返回字符串。
不要忘记,对于转换为字符串,还有Convert.ToString(someType instanceOfThatType),其中someType是一组类型之一,本质上是框架基类型。