【问题标题】:Why I don't need ToString() method inside a MessgeBox.Show () [closed]为什么我不需要 MessgeBox.Show () 中的 ToString() 方法 [关闭]
【发布时间】:2012-09-18 17:33:39
【问题描述】:

我刚刚注意到这也有效:

MessageBox.Show("number of things in the report are  " + myHashSetVariable.Count);

我的印象是我应该使用 myHashSetVariable.Count.ToString()

它是 VS2010 中的某种编译器/解释器改进吗?我用的是VS2010 Pro

【问题讨论】:

标签: c#


【解决方案1】:

首先,这与MessageBox.Show 无关。这与+ 运算符有关。 string + object 的结果等于一个字符串。

语言中的 + 运算符有许多重载(您也可以为用户定义的类型添加自己的重载)。只有两个以object 为参数,即operator+(string, object)operator+(object, string)。在这两种情况下,操作符的实现主体都会在object 参数上调用ToString,然后使用string.Concat 生成结果。

由于您的变量是一个整数,并且它使用operator+string 作为第一个参数,它将匹配operator+(string, object) 而没有其他候选人。

【讨论】:

  • 除了根据 Jon Skeet the + operator is not overloaded on string 的说法。相反,+ 编译为string.Concat
  • @codesparkle 是的,+ 运算符在用户定义类型的情况下的处理方式与在少数本机类型(如string)中的处理方式不同。虽然解决特定重载后发生的情况大不相同,但它仍将使用相同的方法解析规则来确定要调用 operator + 的哪个重载。
【解决方案2】:

隐式调用 ToString 以验证您可以省略消息中的字符串文字,现在您需要显式调用 ToString 以消除编译错误

MessageBox.Show(myHashSetVariable.Count); //This gives the error

【讨论】:

  • @pst 好吧,对于初学者来说,大部分帖子都是在我发表评论后重新编写的,所以我已将其删除。接下来,正如我在回答中所说,MessageBox.Show 与此行为完全无关;它与+ 运算符有关。
【解决方案3】:

你可以这样做:

int intval = 5;
string blah = "This is my string" + intval;

ToString() 在那里被隐式调用。不过,我发现显式调用它是有意义的,以使代码更清晰。

【讨论】:

    【解决方案4】:

    Servy 做对了。以下是一些链接和示例,可能有助于您进一步理解字符串连接和隐式转换的主题。

    C# 语言规范部分7.7.4 Addition operator 声明:

    二元 + 运算符在一个或两个时执行字符串连接 操作数是字符串类型。 [...] 任何非字符串参数都是 通过调用 virtual 转换为其字符串表示形式 ToString 方法继承自类型对象。

    对于 int 预定义类型的简单案例,您会看到根据规范调用 int.ToString()。但是如果你有一个用户定义的类型,你也可能会遇到implicit 转换为字符串(6.4.3 User-defined implicit conversions 中的血腥细节)。

    要进行实验,请定义一个模仿 MessageBox.Show(string) 的方法。重要的是不要直接调用Console.WriteLine,因为它提供了许多Write 重载,包括Write(Int32):

    static void Write(string s)
    {
        Console.WriteLine(s);
    }
    

    还有一些用户定义的类:

    首先,一个没有覆盖或转换的空类。

    class EmptyClass {
    }
    

    还有一个覆盖 Object.ToString 的类。

    class ToStringOnly {
        public override string ToString() {
            return "ToStringOnly";
        }
    }
    

    另一个演示隐式转换为字符串的类:

    class ImplicitConversion {
        static public implicit operator string(ImplicitConversion b) {
            return "Implicit";
        }
    }
    

    最后,我想知道当一个类同时定义隐式转换覆盖 Object.ToString 时会发生什么:

    class ImplicitConversionAndToString {
        static public implicit operator string(ImplicitConversionAndToString b) {
            return "Implicit";
        }
        public override string ToString() {
            return "ToString";
        }
    }
    

    隐式转换测试:

    // Simple string, okay
    Write("JustAString"); // JustAString
    
    // Error: cannot convert from 'int' to 'string'
    //Write(2); 
    
    // EmptyClass cannot be converted to string implicitly,
    // so we have to call ToString ourselves. In this case
    // EmptyClass does not override ToString, so the base class
    // Object.ToString is invoked
    //Write(new EmptyClass()); // Error
    Write(new EmptyClass().ToString()); // StackOverflowCSharp.Program+EmptyClass
    
    // implicit conversion of a user-defined class to string
    Write(new ImplicitConversion()); // Implicit
    
    // while ToStringOnly overrides ToString, it cannot be
    // implicitly converted to string, so we have to again
    // call ToString ourselves. This time, however, ToStringOnly
    // does override ToString, and we get the user-defined text
    // instead of the type information provided by Object.ToString
    //Write(new ToStringOnly()); // ERROR
    Write(new ToStringOnly().ToString());  // "ToStringOnly"
    

    还有一个更相关的字符串连接测试:

    // Simple string
    Write("string"); // "string"
    
    // binary operator with int on the right
    Write("x " + 2); // "x 2"
    
    // binary operator with int on the left
    Write(3 + " x"); // "3 x"
    
    // per the specification, calls Object.ToString
    Write("4 " + new EmptyClass()); // "4 StackOverflowCSharp.Program+EmptyClass"
    
    // the implicit conversion has higher precedence than Object.ToString
    Write("5 " + new ImplicitConversion()); // "5 Implicit"
    
    // when no implicit conversion is present, ToString is called, which
    // in this case is overridden by ToStringOnly
    Write("6 " + new ToStringOnly()); // "6 ToStringOnly"
    

    并用一个定义隐式转换的类来密封它覆盖 Object.ToString():

    // In both cases, the implicit conversion is chosen
    Write( new ImplicitConversionAndToString() ); // "Implicit"
    Write( "8: " + new ImplicitConversionAndToString()); // 8: Implicit
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-18
      • 2021-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-27
      相关资源
      最近更新 更多