在转换变量时语法的最佳实践是什么?

时间:2010-01-12 21:37:18

标签: c#

哪个(如果有的话)更正确?为什么呢?

string someVariable = (string) someOtherVariable;
string someVariable = someOtherVariable.ToString();
string someVariable = someOtherVariable as string;

我已经使用了这三种,但我没有任何偏好或理解为什么一个比另一个好。

10 个答案:

答案 0 :(得分:10)

这些都不是铸造的例子。

这是演员:

string someVariable = (string) someOtherVariable;

这是方法调用:

string someVariable = someOtherVariable.ToString();

这是一个安全演员:

string someVariable = someOtherVariable as string;

第一个和第三个例子是实际演员表。第一个演员有可能抛出InvalidCastException而第三个例子不会抛出该异常。这就是as运算符被称为安全演员的原因。

答案 1 :(得分:6)

这是我关于这个主题的文章。

http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx

至于哪一个是“最正确的”,最正确的是具有你打算传达给程序读者的意思的那个。

“ToString()”传达“这可能不是一个字符串;如果不是,那么我希望从对象中获得一个代表它的字符串。”

“cast”操作符传达“这是一个字符串,如果我错了,我愿意让我的程序崩溃”,或相反,“这不是一个字符串,我想调用用户定义的将此对象转换为字符串“。

“as”运算符表示“这可能是一个字符串,如果不是,我希望结果为空。”

这四件事中的哪一件是什么意思?

答案 2 :(得分:5)

这三个人做了不同的事情 - 没有一个是“更正确”,这取决于你的情况。如果你有一堆可能不是字符串的对象,你可能会使用.ToString()(如果你期望空值,则使用空检查)。

如果您只关心非空字符串,但仍希望接收非字符串,请使用“as”强制转换,然后忽略以null形式出现的值(它们原来是null,或者是非字符串类型)

如果您希望只接收字符串,最好使用(字符串)强制转换。这表达了代码中最佳的意图。

object foo = 5;
string str = (string)foo;    // exception
string str = foo as string;  // null
string str = foo.ToString(); // "5"

object foo = "bar";
string str = (string)foo;    // "bar"
string str = foo as string;  // "bar"
string str = foo.ToString(); // "bar"

object foo = null;
string str = (string)foo;    // null
string str = foo as string;  // null
string str = foo.ToString(); // exception

答案 3 :(得分:2)

如果您认为转换在转发期间失败,则as关键字非常有用。例如,如果我想对控件列表中的类似类型执行相同的操作...让我们说取消选中所有复选框:

foreach (Control ctrl in Controls)
{
    Checkbox box = ctrl as Checkbox;
    if (box != null)
        box.Checked = false;
}

这样,如果我的列表中有其他东西,比如文本框或标签,则不会抛出任何异常(如果失败则只设置变量= null),并且它非常有效。没有异常开销。

答案 4 :(得分:2)

这里不应混淆CAST和CONVERT的想法。转换涉及查看对象,就好像它是另一种类型。转换涉及将对象转换为另一种类型。

如果您打算将CAST转换为字符串,则应使用第一个或第三个字符串。 (选项取决于您在错误条件下想要发生的事情。请参阅bangoker的答案。)

如果您打算将CONVERT转换为字符串,则应使用第二个字符串。 (或者更好,ChaosPandion使用trinary运算符修改了语句。)这是因为ToString方法的行为被定义为将对象转换为字符串表示。

答案 5 :(得分:0)

这是100%的个人偏好,但对我来说,我使用下面的内容:

string someVariable = (string) someOtherVariable;

转换为子类型或父类型时(例如NetworkStream-> Stream)

string someVariable = someOtherVariable.ToString();

转换为新类型(int - > string)

我从不使用后者(作为字符串)方法,主要是因为来自C / C ++背景我更喜欢()并且它更简洁。

答案 6 :(得分:0)

使用括号进行投射和使用“as”进行投射之间存在很大差异。

基本上,括号将抛出异常,而“as”将返回null而不是引发异常。

更详细的信息here

答案 7 :(得分:0)

string someVariable = (string) someOtherVariable;

这是你很好的旧正常投射,如果你试图将某些东西投射到一些它不能被投射的东西上它会引发异常(因此有时你需要检查它们是否是可投射的)

string someVariable = someOtherVariable.ToString();

不是真正的转换,它执行的方法可能来自不同的地方(接口)但是C#中的所有对象都有,因为它们继承自Object对象,它拥有它。它有一个默认操作,它给出了对象类型的名称,但你可以重载它来打印你希望你的类在ToString方法上打印的任何内容。

string someVariable = someOtherVariable as string;

这是一个新的c#强制转换,它首先检查是否可以使用variable is string进行转换然后如果有效则进行转换,如果不是则返回null,这样它就可以是静默的如果您期望异常,则会出错,因为您应该检查null。

基本上

myType as myOtherType 

与:

相同
var something = null;
if(myType is myOtherType)
{
  something = (myType) myotherType;
}

除了将在一步中检查和施放,而不是在2中。

答案 8 :(得分:0)

首先,您应该 avoid casting with AS operator 。链接的文章解释了原因。

其次,如果您希望值不是您所投射的类型,则只能使用 AS运算符。所以你必须手动检查。

obj.ToString()方法调用也不是强制转换,将对象转换为字符串表示形式(如果字符串本身是相同的字符串)。这可以被任何一个阶级淘汰。


作为一般规则,我遵循这个:

  1. 始终使用(Type)施法。
  2. 仅当对象可以是您投射到的其他类型时才使用as运算符。
  3. 如果使用as运算符 - 请始终检查结果为NULL。
  4. 仅在需要显示有关对象的信息时才使用ToString

答案 9 :(得分:0)

如果您对铸造变量的语法最佳做法有疑问,那么我更倾向于使用下一个:

var someVariable = someOtherVariable as string ?? string.Empty;

当然你可以使用someVariableDefaultValue而不是string.Empty。

如果您不是转换为字符串而是转换为某种复杂类型,那么我建议使用下一种语法,有时称为安全导航操作符:

var complexVariable = otherComplexVariable as ComplexType;
if (complexVariable?.IsCondition)
{
   //your code if cast passed and IsCondition is true
}
else
{
   //your code if cast not passed or IsCondition is false
}