在C#中对值类型调用方法时是否隐式执行装箱?

在C#中对值类型调用方法时是否隐式执行装箱?,c#,boxing,autoboxing,C#,Boxing,Autoboxing,假设我做了这样的事情: int x = 5; String s = x.ToString(); 来自Java,我会认为正在对int值进行自动装箱,以使其行为类似于对象并对其调用方法。但我听说在C#中,一切都是对象,没有Java“Integer”类型这样的东西。那么,变量是否被装箱到对象?或者可以直接从C#值类型调用方法?怎么做 C#int是像Java/C中那样的32位空间,还是更大的空间?提前感谢您解答我的疑问。int是一个结构,因此它是在堆栈上声明的,而不是在堆上声明的。然而,c#中的结构可

假设我做了这样的事情:

int x = 5;
String s = x.ToString();
来自Java,我会认为正在对int值进行自动装箱,以使其行为类似于对象并对其调用方法。但我听说在C#中,一切都是对象,没有Java“Integer”类型这样的东西。那么,变量是否被装箱到对象?或者可以直接从C#值类型调用方法?怎么做


C#int是像Java/C中那样的32位空间,还是更大的空间?提前感谢您解答我的疑问。

int
是一个结构,因此它是在堆栈上声明的,而不是在堆上声明的。然而,c#中的结构可以像类一样具有方法、属性和字段。方法
ToString()
是在类型
System.Object
上定义的,所有类和结构都是从
System.Object
派生的。因此,对结构调用.ToString()不会执行任何类型的装箱(将值类型更改为引用类型)

如果你想在c#中看到拳击,可以使用铸造或类似的隐式转换

public void Testing() {
    // 5 is boxed here
    var myBoxedInt = (object)5;

    var myInt = 4;
    // myInt is boxed and sent to the method
    SomeCall(myInt);

}

public void SomeCall(object param1){}

要详细说明@Igor的答案并给出一些细节:

此代码:

public void Test() {
    int x = 5;
    string s = x.ToString();
}
可以将其视为以下假设代码:

public void Test() {
    int x = 5;
    string s = StringInternals.ToString(x);
}

// ...

public static class StringInternals {

    public static string ToString( int x ) {
        // Standard int to -> string implementation
        // Eg, figure out how many digits there are, allocate a buffer to fit them, read out digits one at a time and convert digit to char.
    }

}

对于显式实现
ToString()
value
类型和通常继承的其他方法
System.Object
,在C#中调用方法时避免装箱(假设尚未以其他方式装箱),标准的int类型始终是Int32,并且总是32位。int16还有其他的int…我从来没有意识到结构是从Object派生的-我以为Object是一个类…@JohnStrife-值类型可以有方法,因此也可以有行为。然后,此行为可以调用其他方法(
允许值类型调用方法
)。你所说的“如何”是什么意思?您正在寻找有关如何定义结构和在结构上定义方法的代码吗?@AndrewWilliamson-从技术上讲,结构源于
System.ValueType
,但它随后源于
System.Object
@JohnStrife-正确。它们可以更轻,因为它们是在堆栈上分配的,所以一旦超出范围,内存就会被回收。我之所以说可能是因为一切都取决于它的使用/误用方式。就技术差异而言(如无继承、带参数的构造函数等)可以看出这一点。@JohnStrife-或对对象具有长期引用的结构,或具有许多可变成员的结构(导致意外问题),一个在内存中占用大量空间,然后创建太多空间的结构(因为堆的内存通常比堆栈的内存多(实际上可能是SO),一个用户认为对象本身是可变的(不可能的)结构。我肯定会有更多的空间,但我想不出任何其他想法。