在 C# 中通过引用或值传递对象 [英] Passing Objects By Reference or Value in C#

查看:32
本文介绍了在 C# 中通过引用或值传递对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,我一直认为非原始变量通过引用传递,原始值通过值传递.

In C#, I have always thought that non-primitive variables were passed by reference and primitive values passed by value.

因此,当将任何非原始对象传递给方法时,对方法中的对象所做的任何事情都会影响正在传递的对象.(C# 101 的东西)

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)

但是,我注意到当我传递一个 System.Drawing.Image 对象时,情况似乎并非如此?如果我将 system.drawing.image 对象传递给另一个方法,并将图像加载到该对象上,然后让该方法超出范围并返回调用方法,则该图像不会加载到原始对象上?

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?

这是为什么?

推荐答案

Objects 根本没有通过.默认情况下,对参数进行求值,并将其 value 作为您正在调用的方法的参数的初始值按值传递.现在重要的一点是该值是引用类型的引用 - 一种获取对象(或 null)的方式.调用者可以看到对该对象的更改.但是,当您使用按值传递(所有类型的默认值)时,将参数的值更改为引用不同的对象将可见.

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.

如果要使用pass-by-reference,则必须使用outref,参数类型是否为值类型或引用类型.在这种情况下,实际上变量本身是通过引用传递的,因此参数使用与参数相同的存储位置 - 调用者可以看到参数本身的更改.

If you want to use pass-by-reference, you must use out or ref, 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.

所以:

public void Foo(Image image)
{
    // This change won't be seen by the caller: it's changing the value
    // of the parameter.
    image = Image.FromStream(...);
}

public void Foo(ref Image image)
{
    // This change *will* be seen by the caller: it's changing the value
    // of the parameter, but we're using pass by reference
    image = Image.FromStream(...);
}

public void Foo(Image image)
{
    // This change *will* be seen by the caller: it's changing the data
    // within the object that the parameter value refers to.
    image.RotateFlip(...);
}

我有一篇文章,其中包含更多详细信息.基本上,通过引用传递"并不意味着您认为它意味着什么.

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.

这篇关于在 C# 中通过引用或值传递对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆