通过引用传递和使用 ref

发布于 2024-09-13 15:00:48 字数 647 浏览 3 评论 0原文

我查看了类似的问题并阅读了一些文章。 这篇文章有一些图片可以清楚地说明这一点。

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 关键字进行更改是一种不好的做法(可能是错误的)吗?

I looked at the similar questions and read some articles. THis article has some pictures which makes it clear.

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;
}

Both of the methods have the same effect on this reference type. so why choose ref keyword for reference types?

is it a bad practice (possibly false) to use somefunction(SomeObject so) and modify the object inside the method and expect the changes without using the ref keyword?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

拥抱影子 2024-09-20 15:00:49

.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;
}

The default parameter passing in .Net is done by value. This is true for both value types and reference types. The difference is that with a reference type you are passing a reference to the instance by value vs. the actual object.

The effect is the so reference in the original function and someFunction are independent. Changing which instance the reference refers to has no affect on the other. However because they refer to the same object they can see mutations to that object done by the other (this is why x changes in your example)

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;
}

The ref modifier causes the parameter to be passed by reference instead of value. Effectively there is no copy of the reference, the so in both the original and calling function are the same reference. So resetting one resets the other

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;
}
叫思念不要吵 2024-09-20 15:00:49

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

看看 此 MSDN 页面 可以获得更清晰的解释,并了解一些陷阱

I only use ref when dealing with non reference types e.g. int,decimal etc.

take a look at this MSDN page for a bit of a clearer explanation, and for a bit of a gotcha

终弃我 2024-09-20 15:00:49

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

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 - 将 so 分配给 null 只会更改该函数的本地变量。第二个会导致崩溃(NullReferenceException),因为 so1 已设置为 null。

Classes are already passed by reference (in unmanaged terms so is a pointer to an object). Passing a reference lets you change the underlying variable (you are using a pointer to a pointer). Take this code:

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

The first method will work and you will print out 1 -- assigning so to null just changes a variable that is local to the function. The second one will cause a crash (NullReferenceException) because so1 has been set to null.

假扮的天使 2024-09-20 15:00:49

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

For reference types, by default parameters are passed by reference unless specified to be passed by value. I think this is a safe enough assumption that most .Net dev should know.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文