小编典典

在 C# 中通过引用或值传递对象

all

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

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

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

为什么是这样?


阅读 77

收藏
2022-04-21

共1个答案

小编典典

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

如果要使用传递引用,则 必须 使用outor
ref,无论参数类型是值类型还是引用类型。在这种情况下,实际上变量本身是通过引用传递的,因此参数使用与参数相同的存储位置 -
调用者可以看到参数本身的更改。

所以:

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

我有一篇文章对此进行了更详细的介绍。基本上,“通过引用传递”并不意味着您认为它意味着什么。

2022-04-21