C#中.ToString和"as string"的区别

77

使用以下两个语句有什么区别? 对我来说,第一个"as string"是一种类型转换,而第二个ToString是调用将输入转换为字符串的实际方法?只是想寻找一些见解。

Page.Theme = Session["SessionTheme"] as string;
Page.Theme = Session["SessionTheme"].ToString();

9个回答

109
如果Session["SessionTheme"]不是string类型,as string会返回null.ToString()方法会尝试调用对象的ToString()方法将任何其他类型转换为字符串。 对于大多数内置类型,这将返回已转换为字符串的对象,但对于没有特定.ToString()方法的自定义类型,它将返回对象类型的名称。
object o1 = "somestring";
object o2 = 1;
object o3 = new object();
object o4 = null;

string s = o1 as string;  // returns "somestring"
string s = o1.ToString(); // returns "somestring"
string s = o2 as string;  // returns null
string s = o2.ToString(); // returns "1"
string s = o3 as string;  // returns null
string s = o3.ToString(); // returns "System.Object"
string s = o4 as string;  // returns null
string s = o4.ToString(); // throws NullReferenceException

还有一件重要的事情需要记住,如果对象为null,调用.ToString()将会抛出异常,但使用as string则只会返回null


2
ToString()会“尝试将任何其他类型转换为字符串”吗?对于大多数内置类型,是的。对于您在Session中自定义的内容(例如复杂的User对象),一切都取决于您是否覆盖了ToString()以及您如何在类中实现它。如果未实现,则返回类型信息字符串。 - Wim
2
当然可以。但这里的重点是阐明ToString()和"as string"之间的区别。如果我想提供一个完整的答案,那将需要两页纸的篇幅。 - Philippe Leybaert
4
我的评论已经解释了。它并不长达两页,关键在于“准确”。 - Wim
4
@Wim:准确性有时会让提问者感到困惑。这并不意味着准确性不重要,但有时保持简短的回答更好。 - Philippe Leybaert
1
感谢你们两位的评论 :) 谢谢! - jaywon
显示剩余2条评论

14
as 关键字基本上会检查对象的类型,使用 MSIL 操作码 isinst,如果是,则返回对该对象的引用;否则返回一个 null 引用。它并不像很多人说的那样试图执行强制转换 - 这意味着需要一些异常处理。这并不是这样的情况。 ToString() 简单地调用对象的 ToString() 方法,其实现可以是类中自定义的方法(对于大多数内置类型,这将执行一种到字符串的转换),或者如果没有提供,则调用基类 object 的方法,返回类型信息。

7
Page.Theme = Session["SessionTheme"] as string;

尝试将其转换为字符串

Page.Theme = Session["SessionTheme"].ToString();

调用ToString()方法,其实可以是任何东西。该方法不进行强制类型转换,应该返回此对象的字符串表示形式。


7

我要对Philippe Leybaert所提出的答案进行扩展,因为虽然我找到了比较这四个方法的资源,但我从未找到一个解释将所有四者进行比较。

  • (string)obj:将对象强制转换为字符串。
  • obj as string:尝试将对象转换为字符串类型。如果无法实现,则返回null。
  • obj.ToString():返回对象的字符串表示形式。如果对象为null,则返回空字符串。
  • Convert.ToString(obj):尝试将对象转换为字符串类型。如果无法实现,则返回空字符串。
object o1 = "somestring";
object o2 = 1;
object o3 = new object();
object o4 = null;

Console.WriteLine((string)o1);           // returns "somestring"
Console.WriteLine(o1 as string);         // returns "somestring"
Console.WriteLine(o1.ToString());        // returns "somestring"
Console.WriteLine(Convert.ToString(o1)); // returns "somestring"
Console.WriteLine((string)o2);           // throws System.InvalidCastException
Console.WriteLine(o2 as string);         // returns null
Console.WriteLine(o2.ToString());        // returns "1"
Console.WriteLine(Convert.ToString(o2)); // returns "1"
Console.WriteLine((string)o3);           // throws System.InvalidCastException
Console.WriteLine(o3 as string);         // returns null
Console.WriteLine(o3.ToString());        // returns "System.Object"
Console.WriteLine(Convert.ToString(o3)); // returns "System.Object"
Console.WriteLine((string)o4);           // returns null
Console.WriteLine(o4 as string);         // returns null
Console.WriteLine(o4.ToString());        // throws System.NullReferenceException
Console.WriteLine(Convert.ToString(o4)); // returns string.Empty

从这些结果中,我们可以看到当obj是字符串或null时,(string)objobj as string表现出相同的方式;否则,(string)obj将引发无效转换异常,obj as string将返回null。obj.ToString()Convert.ToString(obj)的行为也相互类似,除非obj为null,在这种情况下,obj.ToString()将引发空引用异常,而Convert.ToString(obj)将返回一个空字符串。

因此,这里是我的建议:
  • (string)obj适用于想要为无法赋给字符串变量(包括null)的类型引发异常的情况
  • obj as string适用于不想引发任何异常,也不想得到非字符串的字符串表示的情况
  • obj.ToString()适用于想要为null引发异常的情况
  • Convert.ToString(obj)适用于不想引发任何异常,也想得到非字符串的字符串表示的情况

编辑:我发现Convert.ToString()实际上根据重载不同而有所不同,因此在此示例中变量被声明为object是很重要的。如果你在nullstring变量上调用Convert.ToString(),它将返回null而不是string.Empty


4
首先,"任何对象作为字符串"和"任何对象.ToString()"在其各自上下文中是完全不同的东西。
string str = any-object as string;

1) 这会将任何对象转换为字符串类型,如果任何对象无法转换为字符串,则此语句将返回null而不抛出任何异常。
2) 这是一个编译器服务。
3) 对于除了字符串以外的任何其他类型,这个方法都能够很好地工作。例如:你可以将任何对象转换为Employee类,其中Employee是你库中定义的一个类。

string str = any-object.ToString();  

1) 这将调用类型定义中任何对象的ToString()方法。由于System.Object定义了ToString()方法,.Net框架中的任何类都可以覆盖ToString()方法。程序员将在任何对象类或结构定义中覆盖ToString(),并编写返回任何对象的适当字符串表示形式的代码,根据任何对象扮演的角色和责任。

2) 您可以定义一个Employee类并覆盖ToString()方法,该方法可以将Employee对象的字符串表示形式返回为“FIRSTNAME - LASTNAME, EMP-CDOE”。

请注意,在这种情况下,程序员对ToString()有控制权,并且与强制转换或类型转换无关。


4
为了让事情更加混乱,C# 6.0引入了null-conditional operator。因此现在可以这样写:
Page.Theme = Session["SessionTheme"]?.ToString();

该方法将返回 null 或者 ToString() 的结果,不会抛出异常。


虽然这很有用,但不确定它如何直接回答关于 as string.ToString() 之间差异的问题。 - crashmstr

1

as string检查对象是否为字符串。如果不是空,它将返回。

调用ToString()会在对象上确实调用ToString()方法。


1
它不会尝试进行强制类型转换。它会检查该类是否是指定类型的实例,如果是,则返回引用,否则返回 null。 - Wim

1

第一个函数如果类是字符串或派生自字符串,则返回类作为字符串(如果不成功则返回null)。

第二个函数调用类的ToString()方法。


0

实际上编写上述代码的最佳方式是执行以下操作:

if (Session["SessionTheme"] != null)
{
    Page.Theme = Session["SessionTheme"].ToString();
}

这样你几乎可以确定它不会引发 NullReferenceException 异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接