大家好,
我得到了按值传递和按引用传递的区别。但是通过ref传递引用(比如array)和通过值传递数组似乎是我无法理解的事情。如何通过引用传递引用?
int[] myArray = {1,2,3};
PassByVal(myArray);
PassByRef(ref myArray);
PassByVal(int[] array)
{ array = new int[] {7,8,9}; // will not work }
PassByRef(ref int[] array)
{ array = new int[] {10,11,12}; } // will work发布于 2010-11-12 06:44:40
我建议你去看看this link。它非常有用,并且包含关于Parameter passing in C#的非常简单的示例。
引用参数不传递函数成员调用中使用的变量的值-它们使用变量本身。不是在函数成员声明中为变量创建新的存储位置,而是使用相同的存储位置,因此函数成员中的变量值和引用参数的值将始终相同。引用参数需要ref修饰符作为声明和调用的一部分-这意味着当你通过引用传递某些东西时,它总是清晰的。让我们看一下前面的示例,只需将参数更改为引用参数:
void Foo (ref StringBuilder x) {
x = null;
}
...
StringBuilder y = new StringBuilder();
y.Append ("hello");
Foo (ref y);
Console.WriteLine (y==null); // will write TRUE示例中的
int[] myArray = {1,2,3};
PassByVal(myArray);
PassByRef(ref myArray);
PassByVal(int[] array){
// the function copy the value of the pointer in a new location of memory
// the "copied" pointer still points to the array 123
// now you are modifying the object pointed by THE COPY of the pointer
// the original pointer still points to array 123
// the copy of the pointer will point to array 456
array = new int[] {7,8,9};
} // will not work
PassByRef(ref int[] array){
// here you are passing the pointer without creating a copy of it in a
// new location of memory
// we have not a original pointer and a "copyed" pointer
// we have only the original pointer and now whe point it to array 10,11,12
array = new int[] {10,11,12};
} // will work发布于 2010-11-12 06:39:08
如果通过引用传递引用,则可以使传入的变量指向新对象。如果通过值传递引用,仍然可以更改对象的状态,但不能使变量指向不同的对象。
示例:
void RefByRef(ref object x)
{
x=new object(2);
}
void RefByValue(object x)
{
x=new object(2);//Only changes a local variable and gets discarded once the function exits
}
void Test()
{
object x1=1;
object x1a=x1;
RefByRef(ref x1);
//x1 is now a boxed 2
//x1a is still a boxed 1
object x2=1;
RefByValue(x2);
//x2 is still a boxed 1
}发布于 2010-11-12 07:13:34
为了回答你的问题,让我们先看看ValueTypes,A,ValueType持有这个值。也就是说,它不会依次指向保存该值的另一个内存位置,而是它的内存位置就是该值。
所以int i= 10;
int j= i;
这里发生的是,i的值的副本被赋值给j,它们都有相同的值,但它们在内存中的位置不同。换句话说,每次将一个值类型赋给另一个值类型时,都会创建一个副本。
与ReferenceTypes签订这份合同。
对象o= 10;
对象p= o;
因为o是一个ReferenceType,所以o指向一个值为10的内存位置(它实际上是装箱的,但我将保持它的简单性)。在下一行中,p现在指向相同的内存位置。换句话说,引用类型有两件事。1.地址指针2.保存实际“事物”的实际内存位置(地址所指向的)。
如果你做到了很远,那么我们就可以继续通过值和引用来传递。
在C#中,参数是通过值传递的。因此,如果要将valueType传递给需要值类型参数的方法,则
int i = 10;
SomeMethod(i);
Console.WriteLine(i);
static void SomeMethod(int value)
{
value = 20;
}当调用SomeMethod时,会将i的值的副本发送给该方法。如果该方法操作参数,它不会影响原始变量i,所以你在控制台窗口中看到的是10;
将其与引用类型联系起来;
class Program
{
static void Main(string[] args)
{
Customer c = new Customer() { Name = "Mike" };
SomeMethod(c);
Console.WriteLine(c.Name);
}
static void SomeMethod(Customer customer)
{
customer.Name = "John";
}
}
class Customer
{
public string Name { get; set; }
}因为c是引用类型。C#通过值传递参数。传递引用的"value“副本。这是c指向的地址的值被传递。在该方法中,由于地址是相同的(它是一个副本,但它指向相同的内存位置),所以该方法能够操作对象的状态。因此,您在控制台窗口中看到的是"John“而不是"Mike”。
但是,如果该方法尝试将另一个实例分配给该参数(在本例中称为"customer“)。然后事情就变了。
class Program
{
static void Main(string[] args)
{
Customer c = new Customer() { Name = "Mike" };
SomeMethod(c);
Console.WriteLine(c.Name);
}
static void SomeMethod(Customer customer)
{
customer = new Customer();
customer.Name = "John";
}
}
class Customer
{
public string Name { get; set; }
}请注意,在该方法中,我们创建了一个新的Customer实例,并将其分配给参数customer,并将这个新实例的名称设置为"John“。我们将在控制台窗口中看到的是"Mike“,而不是john。
这是因为在将原始变量(c)传递给该方法之前,已创建了该变量的副本。而现在在这个方法中,我们有了另一个地址,然后操作这个新地址,这样原始实例就不会受到影响。讲得通?
好吧,如果这有意义的话。那么如果我们真的想让SomeMethod能够做我们想要做的事情呢?那么这个参数不能通过值传递,但是它必须通过引用传递。这意味着变量c和两个部分(它所指向的地址值和地址本身)正在被传递。所以现在你是通过引用来传递引用类型。
class Program
{
static void Main(string[] args)
{
Customer c = new Customer() { Name = "Mike" };
SomeMethod(ref c);
Console.WriteLine(c.Name);
}
static void SomeMethod(ref Customer customer)
{
customer = new Customer();
customer.Name = "John";
}
}
class Customer
{
public string Name { get; set; }
}https://stackoverflow.com/questions/4159943
复制相似问题