在 C# 中通过引用或值传递对象
在C#中,我一直认为非原始变量是通过引用传递的,而原始值是通过值传递的。
因此,当将任何非原始对象传递给方法时,对该方法中的对象所做的任何操作都会影响正在传递的对象。 (C# 101 的东西)
但是,我注意到当我传递 System.Drawing.Image 对象时,情况似乎并非如此?如果我将 System.Drawing.Image 对象传递给另一个方法,并将图像加载到该对象上,然后让该方法超出范围并返回到调用方法,则不会加载该图像在原始对象上?
这是为什么呢?
In C#, I have always thought that non-primitive variables were passed by reference and primitive values passed by value.
So when passing to a method any non-primitive object, anything done to the object in the method would effect the object being passed. (C# 101 stuff)
However, I have noticed that when I pass a System.Drawing.Image
object, that this does not seem to be the case? If I pass a System.Drawing.Image
object to another method, and load an image onto that object, then let that method go out of scope and go back to the calling method, that image is not loaded on the original object?
Why is this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
对象根本不被传递。默认情况下,将对参数进行求值,并按值传递其值,作为您调用的方法的参数的初始值。现在重要的一点是该值是引用类型的引用 - 一种获取对象(或 null)的方法。调用者可以看到对该对象的更改。但是,当您使用按值传递时,更改参数值以引用不同的对象将不可见,这是所有类型的默认值。
如果要使用按引用传递,则无论参数类型是值类型还是引用,必须使用
out
或ref
类型。在这种情况下,实际上变量本身是通过引用传递的,因此参数使用与参数相同的存储位置 - 并且调用者可以看到参数本身的更改。所以:
我有一篇文章对此进行了更多详细介绍。基本上,“通过引用传递”并不意味着您认为的意思。
Objects aren't passed at all. By default, the argument is evaluated and its value is passed, by value, as the initial value of the parameter of the method you're calling. Now the important point is that the value is a reference for reference types - a way of getting to an object (or null). Changes to that object will be visible from the caller. However, changing the value of the parameter to refer to a different object will not be visible when you're using pass by value, which is the default for all types.
If you want to use pass-by-reference, you must use
out
orref
, whether the parameter type is a value type or a reference type. In that case, effectively the variable itself is passed by reference, so the parameter uses the same storage location as the argument - and changes to the parameter itself are seen by the caller.So:
I have an article which goes into a lot more detail in this. Basically, "pass by reference" doesn't mean what you think it means.
添加了很多好的答案。我仍然想做出贡献,也许它会稍微澄清一些。
当您将实例作为参数传递给方法时,它会传递该实例的
副本
。现在,如果您传递的实例是值类型
(驻留在堆栈
中),您将传递该值的副本,因此如果您修改它不会反映在调用者中。如果实例是引用类型,则将引用的副本(同样位于堆栈
中)传递给对象。所以你得到了对同一个对象的两个引用。他们都可以修改对象。但是,如果在方法体内实例化新对象,则引用的副本将不再引用原始对象,它将引用您刚刚创建的新对象。所以你最终会有 2 个引用和 2 个对象。Lots of good answers had been added. I still want to contribute, might be it will clarify slightly more.
When you pass an instance as an argument to the method it passes the
copy
of the instance. Now, if the instance you pass is avalue type
(resides in thestack
) you pass the copy of that value, so if you modify it, it won't be reflected in the caller. If the instance is a reference type you pass the copy of the reference(again resides in thestack
) to the object. So you got two references to the same object. Both of them can modify the object. But if within the method body, you instantiate new object your copy of the reference will no longer refer to the original object, it will refer to the new object you just created. So you will end up having 2 references and 2 objects.还有一个代码示例来展示这一点:
以及输出:
One more code sample to showcase this:
And the output:
我想当你这样做时它会更清楚。我建议下载 LinqPad 来测试这样的事情。
应该输出
WontUpdate
名字:Egli,姓氏:Becerra
UpdateImplicitly
名字:Favio,姓氏:Becerra
UpdateExplicitly< /strong>
名字:法维奥,姓氏:贝塞拉
I guess its clearer when you do it like this. I recommend downloading LinqPad to test things like this.
And that should output
WontUpdate
First name: Egli, Last name: Becerra
UpdateImplicitly
First name: Favio, Last name: Becerra
UpdateExplicitly
First name: Favio, Last name: Becerra
当您将 System.Drawing.Image 类型对象传递给方法时,您实际上是在传递对该对象的引用的副本。
因此,如果在该方法中您要加载新图像,则您将使用新的/复制的引用加载。您没有对原始内容进行更改。
When you pass the the
System.Drawing.Image
type object to a method you are actually passing a copy of reference to that object.So if inside that method you are loading a new image you are loading using new/copied reference. You are not making change in original.
你是如何将对象传递给方法的?
您是否在对象的该方法中执行 new 操作?如果是这样,您必须在方法中使用
ref
。以下链接可以给您更好的想法。
http://dotnetstep.blogspot.com/ 2008/09/passing-reference-type-byval-or-byref.html
How did you pass object to method?
Are you doing new inside that method for object? If so, you have to use
ref
in method.Following link give you better idea.
http://dotnetstep.blogspot.com/2008/09/passing-reference-type-byval-or-byref.html
通过引用传递您只需在函数参数中添加“ref”,然后添加一个
您应该将函数声明为“静态”,因为 main 是 static(#
public void main(String[] args)
)!In Pass By Reference You only add "ref" in the function parameters and one
more thing you should be declaring function "static" because of main is static(#
public void main(String[] args)
)!在最新版本的 C#(撰写本文时为 C# 9)中,对象默认通过
ref
传递。因此,对调用函数中的对象所做的任何更改都将保留在被调用函数中的对象中。In the latest version of C#, which is C# 9 at this time of writing, objects are by default passed by
ref
. So any changes made to the object in the calling function will persist in the object in the called function.