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

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

问题描述

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

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

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

这是为什么?

解决方案

对象根本没有被传递.默认情况下,参数会被评估,并且它的是按值传递的,作为你正在调用的方法的参数的初始值.现在重要的一点是该值是对引用类型的引用 - 一种获取对象(或 null)的方法.调用者可以看到对该对象的更改.但是,当您使用按值传递时,更改参数值以引用不同的对象将可见,这是所有类型的默认设置.

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

所以:

public void Foo(Image image){//调用者不会看到此更改:它正在更改值//参数.图像 = Image.FromStream(...);}public void Foo(ref Image image){//调用者*将*看到此更改:它正在更改值//的参数,但我们使用的是通过引用传递图像 = Image.FromStream(...);}public void Foo(Image image){//调用者*将*看到此更改:它正在更改数据//在参数值引用的对象中.image.RotateFlip(...);}

我有一篇文章,其中详细介绍了这一点.基本上,通过引用传递"并不意味着你认为它意味着什么.

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?

解决方案

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

So:

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天全站免登陆