C#对象/对象
C#C#对象/对象,c#,object,C#,Object,C#对象/对象是值类型还是引用类型 我检查了它们是否可以保留引用,但这些引用不能用于更改对象 using System; class MyClass { public static void Swap(Object obj1, Object obj2) { Console.WriteLine("After Swapping"); obj1 = 100; obj2 = 200; } } class MainClass {
对象
/对象
是值类型还是引用类型
我检查了它们是否可以保留引用,但这些引用不能用于更改对象
using System;
class MyClass
{
public static void Swap(Object obj1, Object obj2)
{
Console.WriteLine("After Swapping");
obj1 = 100;
obj2 = 200;
}
}
class MainClass
{
static void Main(string[] args)
{
Object obj1 = new Object ();
obj1 = 10;
Object obj2 = new Object ();
obj2 = 20;
Console.WriteLine(obj1.ToString());
Console.WriteLine(obj2.ToString());
MyClass.Swap(obj1, obj2);
Console.WriteLine(obj1.ToString());
Console.WriteLine(obj2.ToString());
Console.ReadLine();
}
}
它是一个引用类型-如果您查看,您将看到它被声明为一个类。所有类都是引用类型 是的,对于
System.ValueType
和System.Enum
,情况也是如此-它们都是引用类型,尽管名称不同。。。但值类型是从它们派生的
编辑:您的更新显示您真正困惑的是参数传递。请参阅我在和上的文章。这是一个引用类型-如果您查看,您将看到它被声明为类。所有类都是引用类型 是的,对于
System.ValueType
和System.Enum
,情况也是如此-它们都是引用类型,尽管名称不同。。。但值类型是从它们派生的
编辑:您的更新显示您真正困惑的是参数传递。请参阅我关于和的文章。因为
对象
是所有对象之母它是引用类型因为对象
是所有对象之母它是引用类型您在交换
中所做的更改仅限于此-您只在玩指针(和装箱),函数外的引用保持不变(您有4个引用)。如果更改了方法的签名,您将看到差异:
尝试交换(参考对象obj1,参考对象obj2)
同样的道理也适用于
Object obj1 = new Object ();
obj1 = 10;
顺便说一下,这并不比对象obj1=10;
好
若要查看对象是否确实是引用类型,请使用具有属性的类,例如:
class Foo {
public int Value {get; set;}
}
在
Swap
中更改对象的值
,您将看到对主程序的影响。您在Swap
中所做的更改仅限于此-您只玩指针(和装箱),函数外的引用保持不变(您有4个引用)。如果更改了方法的签名,您将看到差异:
尝试交换(参考对象obj1,参考对象obj2)
同样的道理也适用于
Object obj1 = new Object ();
obj1 = 10;
顺便说一下,这并不比对象obj1=10;
好
若要查看对象是否确实是引用类型,请使用具有属性的类,例如:
class Foo {
public int Value {get; set;}
}
在
Swap
中更改对象的值
,您将看到对主程序的影响。您应该这样编写代码:
using System;
class MyClass
{
public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref'
{
Console.WriteLine("After Swapping");
obj1 = 100;
obj2 = 200;
}
}
class MainClass
{
static void Main(string[] args)
{
Object obj1 = new Object ();
obj1 = 10;
Object obj2 = new Object ();
obj2 = 20;
Console.WriteLine(obj1.ToString());
Console.WriteLine(obj2.ToString());
MyClass.Swap(ref obj1, ref obj2); // Use keyword 'ref'
Console.WriteLine(obj1.ToString());
Console.WriteLine(obj2.ToString());
Console.ReadLine();
}
}
您可以在中阅读有关关键字“ref”的更多信息
引用MSDN:
传递参数(C#编程
指南)
在C#中,参数可以通过
通过值或引用。传递
通过引用启用参数
函数成员、方法、属性,
索引器、运算符和构造函数
更改参数值的步骤
让这种变化持续下去。通过
通过引用创建参数时,请使用ref
或out关键字。仅为简单起见
ref关键字用于
本主题中的示例。有关更多信息
关于差异的信息
在ref和out之间,参见ref(C#
参考),输出(C#参考),以及
使用ref和out(C)传递数组#
编程指南)。例如:
class Foo {
public int Value {get; set;}
}
(c) 您应该编写如下代码:
using System;
class MyClass
{
public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref'
{
Console.WriteLine("After Swapping");
obj1 = 100;
obj2 = 200;
}
}
class MainClass
{
static void Main(string[] args)
{
Object obj1 = new Object ();
obj1 = 10;
Object obj2 = new Object ();
obj2 = 20;
Console.WriteLine(obj1.ToString());
Console.WriteLine(obj2.ToString());
MyClass.Swap(ref obj1, ref obj2); // Use keyword 'ref'
Console.WriteLine(obj1.ToString());
Console.WriteLine(obj2.ToString());
Console.ReadLine();
}
}
您可以在中阅读有关关键字“ref”的更多信息
引用MSDN:
传递参数(C#编程
指南)
在C#中,参数可以通过
通过值或引用。传递
通过引用启用参数
函数成员、方法、属性,
索引器、运算符和构造函数
更改参数值的步骤
让这种变化持续下去。通过
通过引用创建参数时,请使用ref
或out关键字。仅为简单起见
ref关键字用于
本主题中的示例。有关更多信息
关于差异的信息
在ref和out之间,参见ref(C#
参考),输出(C#参考),以及
使用ref和out(C)传递数组#
编程指南)。例如:
class Foo {
public int Value {get; set;}
}
(c) 这是因为obj1和obj2的运行时类型是
System.Int32
(请使用obj1.GetType().ToString()
进行检查),即值类型。交换函数中没有引用副本。相反,它只执行装箱和取消装箱操作,这对实际变量没有影响。这是因为obj1和obj2的运行时类型是System.Int32
(请使用obj1.GetType().ToString()
),即值类型。交换函数中没有引用副本。相反,它只执行装箱和取消装箱操作,这对实际变量没有影响。请注意
Object obj1 = new Object ();
obj1 = 10;
同:
Object obj1 = 10;
因为编译器通过“装箱”将值类型int
转换为引用类型。在Swap方法中,您再次装箱,覆盖引用参数
所以Kobi和Dreamwalker的解决方案,使用ref参数,将实际起作用:
public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref'
但这远非理想
更好的解决方案是通用方法:
static void Swap<T>(ref T x, ref T y)
{
T z = x; x = y; y = z;
}
静态无效交换(参考T x,参考T y)
{
T z=x;x=y;y=z;
}
因此编译器可以为引用类型和值类型生成最合适的代码。请注意
Object obj1 = new Object ();
obj1 = 10;
同:
Object obj1 = 10;
因为编译器通过“装箱”将值类型int
转换为引用类型。在Swap方法中,您再次装箱,覆盖引用参数
所以Kobi和Dreamwalker的解决方案,使用ref参数,将实际起作用:
public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref'
但这远非理想
更好的解决方案是通用方法:
static void Swap<T>(ref T x, ref T y)
{
T z = x; x = y; y = z;
}
静态无效交换(参考T x,参考T y)
{
T z=x;x=y;y=z;
}
因此,编译器可以为引用和值类型生成最合适的代码。请发布一些代码,证明您无法更改对象引用。请发布