通过引用传递并使用ref

时间:2010-08-05 02:10:18

标签: c# .net parameters reference methods

我查看了类似的问题并阅读了一些文章。 THis文章中有一些图片说清楚。

SomeObject so = new SomeObject();
somefunction(so);
Console.write(so.x); // will print 1

SomeObject so1 = new SomeObject();
somefunctionByRef(so1);
Console.write(so1.x); // will print 1


static void somefunction(SomeObject so)
{
    so.x = 1;
}

public void somefunctionByRef(ref SomeObject so)
{
    so.x = 1;
}

这两种方法对此引用类型具有相同的效果。那么为什么选择ref关键字作为参考类型?

使用somefunction(SomeObject so)并修改方法中的对象并期望更改而不使用ref关键字是不好的做法(可能是假的)?

4 个答案:

答案 0 :(得分:3)

传入.Net的默认参数是按值完成的。对于值类型和引用类型都是如此。不同之处在于,对于引用类型,您将通过值与实际对象传递对实例的引用。

效果是原始函数中的so引用,someFunction是独立的。更改引用引用的实例对另一个实例没有影响。但是因为它们引用相同的对象,所以可以看到另一个对象完成的对象的突变(这就是为什么x在你的例子中发生了变化)

SomeObject so = new SomeObject();
so.x = 42;
somefunction(so);
Console.Write(so.x); // will print 42

static void somefunction(SomeObject so) {
  so = new SomeObject();
  so.x = 13;
}

ref修饰符导致参数通过引用而不是值传递。实际上没有引用的副本,原始函数和调用函数中的so是相同的引用。所以重置一个重置另一个

SomeObject so = new SomeObject();
so.x = 42;
somefunction(ref so);
Console.Write(so.x); // will print 13

static void somefunction(ref SomeObject so) {
  so = new SomeObject();
  so.x = 13;
}

答案 1 :(得分:1)

我在处理非引用类型时只使用ref,例如int,decimal等。

看看this MSDN page以获得更清晰的解释,以及一些问题

答案 2 :(得分:1)

类已经通过引用传递(在非托管术语中,因此是指向对象的指针)。传递引用可以更改基础变量(您正在使用指向指针的指针)。拿这个代码:

static void foo(SomeObject so)
{
    so.x = 1;
    so = null;
}

static void bar(ref SomeObject so)
{
    so.x = 1;
    so = null;
}

SomeObject so1 = new SomeObject(); 
foo(so1); 
Console.write(so1.x); // will print 1 
bar(so1); 
Console.write(so1.x); // crash

第一种方法将起作用,你将打印出1 - 指定为null只是更改函数本地的变量。第二个将导致崩溃(NullReferenceException),因为so1已设置为null。

答案 3 :(得分:0)

对于引用类型,默认情况下,参数通过引用传递,除非指定通过值传递。我认为这是一个足够安全的假设,大多数.Net开发者都应该知道。