简体   繁体   English

C# 中 .ToString 和“作为字符串”的区别

[英]Difference between .ToString and “as string” in C#

What is the difference between using the two following statements?使用以下两个语句有什么区别? It appears to me that the first "as string" is a type cast, while the second ToString is an actual call to a method that converts the input to a string?在我看来,第一个“作为字符串”是类型转换,而第二个 ToString 是对将输入转换为字符串的方法的实际调用? Just looking for some insight if any.只是寻找一些见解,如果有的话。

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

If Session["SessionTheme"] is not a string , as string will return null .如果Session["SessionTheme"]不是string ,则as string将返回null

.ToString() will try to convert any other type to string by calling the object's ToString() method. .ToString()将尝试通过调用对象的ToString()方法将任何其他类型转换为字符串。 For most built-in types this will return the object converted to a string, but for custom types without a specific .ToString() method, it will return the name of the type of the object.对于大多数内置类型,这将返回转换为字符串的对象,但对于没有特定.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

Another important thing to keep in mind is that if the object is null , calling .ToString() will throw an exception, but as string will simply return null .要记住的另一件重要事情是,如果对象为null ,则调用.ToString()将引发异常,但as string将简单地返回null

The as keyword will basically check whether the object is an instance of the type, using MSIL opcode isinst under the hood. as关键字将基本上检查对象是否is该类型的实例,在isinst使用 MSIL 操作码isinst If it is, it returns the reference to the object, else a null reference.如果是,则返回对对象的引用,否则返回空引用。

It does not, as many say, attempt to perform a cast as such - which implies some kind of exception handling.正如许多人所说,它没有尝试执行这样的强制转换——这意味着某种异常处理。 Not so.不是这样。

ToString() , simply calls the object's ToString() method, either a custom one implemented by the class (which for most in-built types performs a conversion to string) - or if none provided, the base class object 's one, returning type info. ToString() ,简单地调用对象的ToString()方法,或者是由类实现的自定义方法(对于大多数内置类型执行到字符串的转换) - 或者如果没有提供,则基类object的一个,返回输入信息。

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

tries to cast to a string尝试转换为字符串

whereas然而

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

calls the ToString() method, which can be anything really.调用ToString()方法,它实际上可以是任何东西。 This method doesn't cast, it should return a string representation of this object.此方法不强制转换,它应返回此对象的字符串表示形式。

First of all " any-object as string " and " any-object.ToString() " are completely different things in terms of their respective context.首先,“ any-object as string ”和“ any-object.ToString() ”就它们各自的上下文而言是完全不同的东西。

string str = any-object as string;

1) This will cast any-object as string type and if any-object is not castable to string then this statement will return null without throwing any exception. 1) 这会将 any-object 强制转换为 string 类型,如果 any-object 不可强制转换为 string,则此语句将返回 null 而不会引发任何异常。
2) This is a compiler-service. 2)这是一个编译器服务。
3) This works pretty much well for any other type other than string, ex: you can do it as any-object as Employee, where Employee is a class defined in your library. 3) 这对于字符串以外的任何其他类型都非常有效,例如:您可以将其作为任何对象作为 Employee 来执行,其中 Employee 是在您的库中定义的类。

string str = any-object.ToString();  

1) This will call ToString() of any-object from type-defination. 1) 这将从类型定义中调用任何对象的 ToString()。 Since System.Object defines ToString() method any class in .Net framework has ToString() method available for over-riding.由于 System.Object 定义了 ToString() 方法,.Net 框架中的任何类都有 ToString() 方法可用于覆盖。 The programmer will over-ride the ToString() in any-object class or struct defination and will write the code that return suitable string representation of any-object according to responsibility and role played by any-object.程序员将覆盖任何对象类或结构定义中的 ToString(),并将根据任何对象的职责和角色编写返回任何对象的合适字符串表示的代码。
2) Like you can define a class Employee and over-ride ToString() method which may return Employee object's string representation as "FIRSTNAME - LASTNAME, EMP-CDOE" . 2)就像您可以定义一个类 Employee 并覆盖 ToString() 方法,该方法可能将 Employee 对象的字符串表示形式返回为 "FIRSTNAME - LASTNAME, EMP-CDOE" 。

Note that the programmer has control over ToString() in this case and it has got nothing to do with casting or type-conversion.请注意,在这种情况下,程序员可以控制 ToString() 并且它与强制转换或类型转换无关。

I'm extending Philippe Leybaert's accepted answer a bit because while I have found resources comparing three of these, I've never found an explanation that compares all four.我正在扩展 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

From these results we can see that (string)obj and obj as string behave the same way as each other when obj is a string or null;从这些结果我们可以看出,当obj是字符串或 null 时, (string)objobj as string行为方式相同; otherwise (string)obj will throw an invalid cast exception and obj as string will just return null.否则(string)obj将抛出无效的强制转换异常,而obj as string将只返回 null。 obj.ToString() and Convert.ToString(obj) also behave the same way as each other except when obj is null, in which case obj.ToString() will throw a null reference exception and Convert.ToString(obj) will return an empty string. obj.ToString()Convert.ToString(obj)行为方式也相同,除非obj为 null,在这种情况下obj.ToString()将抛出一个 null 引用异常并且Convert.ToString(obj)将返回一个空字符串。

So here are my recommendations:所以这里是我的建议:

  • (string)obj works best if you want to throw exceptions for types that can't be assigned to a string variable (which includes null) (string)obj如果您想为无法分配给字符串变量(包括空值)的类型抛出异常,则效果最佳
  • obj as string works best if you don't want to throw any exceptions and also don't want string representations of non-strings如果您不想抛出任何异常并且也不想非字符串的字符串表示,则obj as string效果最佳
  • obj.ToString() works best if you want to throw exceptions for null如果您想为 null 抛出异常, obj.ToString()效果最佳
  • Convert.ToString(obj) works best if you don't want to throw any exceptions and want string representations of non-strings如果您不想抛出任何异常并想要非字符串的字符串表示形式,则Convert.ToString(obj)效果最佳

EDIT: I've discovered that Convert.ToString() actually treats null differently depending on the overload, so it actually matters that the variable was declared as an object in this example.编辑:我发现Convert.ToString()实际上根据重载对null处理方式不同,因此在此示例中将变量声明为object实际上很重要。 If you call Convert.ToString() on a string variable that's null then it will return null instead of string.Empty .如果您在为nullstring变量上调用Convert.ToString() ,那么它将返回null而不是string.Empty

To confuse the matter further, C# 6.0 has introduced the null-conditional operator .为了进一步混淆这个问题,C# 6.0 引入了空条件运算符 So now this can also be written as:所以现在这也可以写成:

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

Which will return either null or the result from ToString() without throwing an exception.这将返回 null 或 ToString() 的结果而不会引发异常。

The as string check is the object is a string. as string检查对象是字符串。 If it isn't a null it returned.如果它不是 null 则返回。

The call to ToString() will indeed call the ToString() method on the object.ToString()的调用确实会调用对象上的ToString()方法。

The first one returns the class as a string if the class is a string or derived from a string (returns null if unsuccessful).如果类是字符串或从字符串派生,则第一个将类作为字符串返回(如果不成功,则返回 null)。

The second invokes the ToString() method on the class.第二个调用类上的 ToString() 方法。

Actually the best way of writing the code above is to do the following:实际上,编写上述代码的最佳方法是执行以下操作:

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

That way you're almost certain that it won't cast a NullReferenceException.这样您几乎可以肯定它不会抛出 NullReferenceException。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM