【问题标题】:Difference between .ToString and "as string" in C#C# 中 .ToString 和 \"as string\" 的区别
【发布时间】:2022-12-22 02:55:29
【问题描述】:

使用以下两个语句有什么区别?在我看来,第一个“作为字符串”是类型转换,而第二个 ToString 是对将输入转换为字符串的方法的实际调用?只是寻找一些见解(如果有的话)。

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

【问题讨论】:

标签: c# string tostring


【解决方案1】:

如果Session["SessionTheme"]不是stringas 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

【讨论】:

  • ToString() 会“尝试将任何其他类型转换为字符串”吗?对于大多数内置类型,是的。在 Session 中使用您自己的自定义内容,比如说一个复杂的用户对象,这一切都取决于您是否覆盖了 ToString() 以及您如何在您的类中实现它。如果未实现,它将返回类型信息字符串。
  • 是的当然。但这里的重点是说明 ToString() 和“as string”之间的区别。如果我想提供一个完整的答案,那将是 2 页长
  • 我的评论解释了这一点。那不是 2 页长。这是关于成为准确的.
  • @Wim:准确有时会使 OP 感到困惑。这并不意味着准确性不是一件好事,但有时最好保持简短的回答
  • 感谢你们两个 cmets :) 谢谢!
【解决方案2】:

as 关键字将基本上检查对象 is 是否是该类型的实例,在后台使用 MSIL 操作码 isinst。如果是,则返回对该对象的引用,否则返回空引用。

不像很多人说的那样,尝试执行这样的转换——这意味着某种异常处理。不是这样。

ToString(),简单地调用对象的ToString()方法,或者是类实现的自定义方法(对于大多数内置类型执行到字符串的转换)——或者如果没有提供,基类object的方法, 返回类型信息。

【讨论】:

    【解决方案3】:

    我稍微扩展了 Philippe Leybaert 接受的答案,因为虽然我找到了比较其中三个的资源,但我从未找到比较所有四个的解释。

    • (string)obj
    • obj as string
    • obj.ToString()
    • 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 为空,在这种情况下,obj.ToString() 将抛出空引用异常,而 Convert.ToString(obj) 将返回空字符串。

    所以这是我的建议:

    • (string)obj 如果您想为无法分配给字符串变量(包括 null)的类型抛出异常,效果最佳
    • obj as string 如果你不想抛出任何异常,也不想要非字符串的字符串表示,那么效果最好
    • obj.ToString() 如果你想为 null 抛出异常,效果最好
    • Convert.ToString(obj) 如果你不想抛出任何异常并且想要非字符串的字符串表示,那么效果最好

    编辑:我发现 Convert.ToString() 实际上根据重载不同地对待 null,所以在这个例子中变量被声明为 object 实际上很重要。如果您在 string 变量(即 null)上调用 Convert.ToString(),那么它将返回 null 而不是 string.Empty

    【讨论】:

      【解决方案4】:
      Page.Theme = Session["SessionTheme"] as string;
      

      尝试转换为字符串

      然而

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

      调用 ToString() 方法,它实际上可以是任何东西。此方法不转换,它应该返回此对象的字符串表示形式。

      【讨论】:

        【解决方案5】:

        首先 ”任何对象作为字符串“ 和 ”任何对象.ToString()" 就其各自的上下文而言是完全不同的事物。

        string str = any-object as string;
        

        1) 这会将 any-object 转换为字符串类型,如果 any-object 不可转换为 string 则此语句将返回 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() 并且它与强制转换或类型转换无关。

        【讨论】:

          【解决方案6】:

          为了进一步混淆问题,C# 6.0 引入了null-conditional operator。所以现在这也可以写成:

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

          它将返回 null 或 ToString() 的结果而不抛出异常。

          【讨论】:

          • 虽然这很有用,但不确定它如何直接回答 as string.ToString() 之间的区别问题。
          【解决方案7】:

          as string 检查对象是一个字符串。如果它不是 null,则返回。

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

          【讨论】:

          • 它不会尝试投射。它检查该类是否是指定类型的实例,如果是则返回引用,否则返回 null。
          【解决方案8】:

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

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

          【讨论】:

            【解决方案9】:

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

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

            这样您几乎可以确定它不会抛出 NullReferenceException。

            【讨论】:

              猜你喜欢
              • 2011-01-07
              • 2014-07-14
              • 2010-10-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-12-26
              • 2018-07-28
              相关资源
              最近更新 更多