在c#中,我一直认为非基本变量是通过引用传递的,而基本值是通过值传递的。

因此,当向一个方法传递任何非基本对象时,在方法中对该对象所做的任何操作都会影响正在传递的对象。(c# 101的东西)

然而,我已经注意到,当我传递一个System.Drawing.Image对象,这似乎不是这样的情况?如果我将system。drawing。image对象传递给另一个方法,并将图像加载到该对象上,然后让该方法超出作用域并返回调用方法,图像没有加载到原始对象上?

为什么会这样?


当前回答

如何将对象传递给方法?

你在那个for object方法中做了新的吗?如果是,你必须使用ref in method。

下面的链接给你更好的想法。

http://dotnetstep.blogspot.com/2008/09/passing-reference-type-byval-or-byref.html

其他回答

在Pass By Reference中,只在函数参数和一个参数中添加“ref” 更多的事情你应该声明函数“static”,因为main是静态的(#public void main(String[] args))!

namespace preparation
{
  public  class Program
    {
      public static void swap(ref int lhs,ref int rhs)
      {
          int temp = lhs;
          lhs = rhs;
          rhs = temp;
      }
          static void Main(string[] args)
        {
            int a = 10;
            int b = 80;

  Console.WriteLine("a is before sort " + a);
            Console.WriteLine("b is before sort " + b);
            swap(ref a, ref b);
            Console.WriteLine("");
            Console.WriteLine("a is after sort " + a);
            Console.WriteLine("b is after sort " + b);  
        }
    }
}

还有一个代码示例可以展示这一点:

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 TestPlain(int i)
{
    i = 5;
}

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

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

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

输出:

测试平原:0 测试参考:5 TestObjPlain:test TestObjRef:TestObjRef

我想当你这样做的时候会更清楚。我建议下载LinqPad来测试这样的事情。

void Main()
{
    var Person = new Person(){FirstName = "Egli", LastName = "Becerra"};

    //Will update egli
    WontUpdate(Person);
    Console.WriteLine("WontUpdate");
    Console.WriteLine($"First name: {Person.FirstName}, Last name: {Person.LastName}\n");

    UpdateImplicitly(Person);
    Console.WriteLine("UpdateImplicitly");
    Console.WriteLine($"First name: {Person.FirstName}, Last name: {Person.LastName}\n");

    UpdateExplicitly(ref Person);
    Console.WriteLine("UpdateExplicitly");
    Console.WriteLine($"First name: {Person.FirstName}, Last name: {Person.LastName}\n");
}

//Class to test
public class Person{
    public string FirstName {get; set;}
    public string LastName {get; set;}

    public string printName(){
        return $"First name: {FirstName} Last name:{LastName}";
    }
}

public static void WontUpdate(Person p)
{
    //New instance does jack...
    var newP = new Person(){FirstName = p.FirstName, LastName = p.LastName};
    newP.FirstName = "Favio";
    newP.LastName = "Becerra";
}

public static void UpdateImplicitly(Person p)
{
    //Passing by reference implicitly
    p.FirstName = "Favio";
    p.LastName = "Becerra";
}

public static void UpdateExplicitly(ref Person p)
{
    //Again passing by reference explicitly (reduntant)
    p.FirstName = "Favio";
    p.LastName = "Becerra";
}

然后输出

WontUpdate

名:Egli,姓:Becerra

更新隐式

名:法维奥,姓:贝塞拉

UpdateExplicitly

名:法维奥,姓:贝塞拉

很多好的答案被添加了进来。我还是想做点贡献,可能会更清楚一点。

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 a value type(resides in the stack) 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 the stack) 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.

Employee e = new Employee();
e.Name = "Mayur";

//Passes the reference as value. Parameters passed by value(default).
e.ReferenceParameter(e);

Console.WriteLine(e.Name); // It will print "Shiv"

 class Employee {

   public string Name { get; set; }

   public void ReferenceParameter(Employee emp) {

     //Original reference value updated.
    emp.Name = "Shiv";

    // New reference created so emp object at calling method will not be updated for below changes.
    emp = new Employee();
    emp.Name = "Max";
  }
}