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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (20)

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

所以当传递给方法的任何非原始对象时,对方法中的对象做的任何事情都会影响被传递的对象。

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

为什么是这样?

提问于
用户回答回答于

默认情况下,参数被计算并且其通过被传递为你调用的方法的参数的初始值。现在重要的一点是,该值是引用类型的参考 - 一种获取对象(或null)的方法。该对象的更改将从调用者可见。但是,如果使用按值传递(这是所有类型的默认值),则更改参数的值以引用不同的对象将可见。

如果要使用传递引用,则必须使用outref,无论参数类型是值类型还是引用类型。在这种情况下,实际上变量本身是通过引用传递的,所以参数使用与参数相同的存储位置

所以:

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

用户回答回答于

有一个代码示例:

void Main()
{


    int k = 0;
    TestPlain(k);
    Console.WriteLine("TestPlain:" + k);

    TestRef(ref k);
    Console.WriteLine("TestRef:" + k);

    string t = "test";

    TestObjPlain( t);
    Console.WriteLine("TestObjPlain:" +t);

    TestObjRef(ref t);
    Console.WriteLine("TestObjRef" + t);
}

public static void TestRef(ref int i)
{
    i = 5;
}

public  static void TestPlain(int i)
{
    i = 5;
}

public static void TestObjRef(ref string s)
{
    s = "TestObjRef";
}

public static void TestObjPlain(string s)
{
    s = "TestObjPlain";
}

输出:

  • TestPlain:0
  • TestRef:5
  • TestObjPlain:test
  • TestObjRefTestObjRef

扫码关注云+社区