Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#函数参数中提及ref_C#_C# 4.0 - Fatal编程技术网

在C#函数参数中提及ref

在C#函数参数中提及ref,c#,c#-4.0,C#,C# 4.0,我创建了一个函数,并在其中传递字符串数组,如string[]aa=null 在函数定义中,我对它进行了一些更新,然后我发现在执行/返回函数时,它的值没有更新。我无法理解C#中哪些内容需要提到ref关键字。它不是总是通过引用传递参数吗?为什么需要提到ref?哪些是需要用ref提及的对象,以便通过引用传递 代码是这样的,只是试图显示我在做什么,我无法在不使用ref的情况下更新值 string[] temp = null foo(ref temp); //function definition v

我创建了一个函数,并在其中传递字符串数组,如string[]aa=null
在函数定义中,我对它进行了一些更新,然后我发现在执行/返回函数时,它的值没有更新。我无法理解C#中哪些内容需要提到ref关键字。它不是总是通过引用传递参数吗?为什么需要提到ref?哪些是需要用ref提及的对象,以便通过引用传递

代码是这样的,只是试图显示我在做什么,我无法在不使用ref的情况下更新值

string[] temp = null 
foo(ref temp); 
//function definition
void foo (ref string[] temp) 
{
temp = {"Hello World ","You must be updated now"}
}
foreach(string s in temp)
System.Console.WriteLine(s)

你在错综复杂的问题上有点弄错了。如果您传递一个引用对象,那么它将按值传递引用(继续阅读,希望它会变得更有意义)。但是,这并不意味着它是按ref传递的。事实上,默认情况下,C#参数是按值传递的

这段代码解释了我所说的按值传递引用的意思

在C#中,参数(默认情况下)通过值传递,这意味着 它们在传递给方法时被隐式复制。对于值类型 参数,这意味着物理复制实例(在相同的 p2的复制方式),而对于引用类型,它意味着复制 参考(以相同的方式复制f2)

。但是,在您的例子中,您正在传入对象,然后在方法中使用新引用创建一个新对象。因此,原始引用保持不变,您可以通过执行更新而不是全新创建来看到这一点。当您显式地说ref时,您现在正在向引用传递一个引用,因此它可以工作,因为您只使用指向该引用的指针,并且当您创建新对象时,它将被放置到该引用位置

正如eouw0o83hf所提到的,如果您正在创建一个全新的对象,那么您应该使用
out
来表示这一点
ref
通常更多地用于不通过引用传递的值对象

总结如下:

  • 如果它是一种值类型,并且您希望更新该值并使其处处反映,则需要使用
    ref
  • 如果是引用类型
    • 如果您希望更新该值,使其反映在所有地方,则可以正常地传递它(无
      ref
      out
    • 如果您希望在方法中创建一个全新的实例并将其反映出来,那么应该使用
      out
更新


你在错综复杂的问题上有点弄错了。如果您传递一个引用对象,那么它将按值传递引用(继续阅读,希望它会变得更有意义)。但是,这并不意味着它是按ref传递的。事实上,默认情况下,C#参数是按值传递的

这段代码解释了我所说的按值传递引用的意思

在C#中,参数(默认情况下)通过值传递,这意味着 它们在传递给方法时被隐式复制。对于值类型 参数,这意味着物理复制实例(在相同的 p2的复制方式),而对于引用类型,它意味着复制 参考(以相同的方式复制f2)

。但是,在您的例子中,您正在传入对象,然后在方法中使用新引用创建一个新对象。因此,原始引用保持不变,您可以通过执行更新而不是全新创建来看到这一点。当您显式地说ref时,您现在正在向引用传递一个引用,因此它可以工作,因为您只使用指向该引用的指针,并且当您创建新对象时,它将被放置到该引用位置

正如eouw0o83hf所提到的,如果您正在创建一个全新的对象,那么您应该使用
out
来表示这一点
ref
通常更多地用于不通过引用传递的值对象

总结如下:

  • 如果它是一种值类型,并且您希望更新该值并使其处处反映,则需要使用
    ref
  • 如果是引用类型
    • 如果您希望更新该值,使其反映在所有地方,则可以正常地传递它(无
      ref
      out
    • 如果您希望在方法中创建一个全新的实例并将其反映出来,那么应该使用
      out
更新

C#始终按值传递参数,除非使用
ref
out
修饰符

string[] temp = { "zero", "one", "two" };
MutateByVal(temp);
MutateByRef(ref temp);    

void MutateByVal(string[] arr)
{
    // arr and temp are separate references to the same array
    // the value of arr (a reference) is a copy of the value of temp

    // mutate the array referenced by arr
    arr[1] = "mutated!";
    // arr and temp still point at the same array
    // so both arr and temp now contain { "zero", "mutated!", "two" }

    // re-assign arr
    arr = new[] { "blah", "blah", "blah" };
    // arr and temp now point at different arrays
    // arr now contains { "blah", "blah", "blah" }
    // temp still contains { "zero", "mutated!", "two" }
}

void MutateByRef(ref string[] arr)
{
    // arr is an alias for temp
    // that is, they are two different names for the same reference

    // mutate the array referenced by arr
    arr[1] = "mutated!";
    // arr and temp are the same reference
    // so both arr and temp now contain { "zero", "mutated!", "two" }

    // re-assign arr
    arr = new[] { "blah", "blah", "blah" };
    // arr and temp are the same reference
    // so both arr and temp now contain { "blah", "blah", "blah" }
}
C始终按值传递参数,除非使用
ref
out
修饰符

string[] temp = { "zero", "one", "two" };
MutateByVal(temp);
MutateByRef(ref temp);    

void MutateByVal(string[] arr)
{
    // arr and temp are separate references to the same array
    // the value of arr (a reference) is a copy of the value of temp

    // mutate the array referenced by arr
    arr[1] = "mutated!";
    // arr and temp still point at the same array
    // so both arr and temp now contain { "zero", "mutated!", "two" }

    // re-assign arr
    arr = new[] { "blah", "blah", "blah" };
    // arr and temp now point at different arrays
    // arr now contains { "blah", "blah", "blah" }
    // temp still contains { "zero", "mutated!", "two" }
}

void MutateByRef(ref string[] arr)
{
    // arr is an alias for temp
    // that is, they are two different names for the same reference

    // mutate the array referenced by arr
    arr[1] = "mutated!";
    // arr and temp are the same reference
    // so both arr and temp now contain { "zero", "mutated!", "two" }

    // re-assign arr
    arr = new[] { "blah", "blah", "blah" };
    // arr and temp are the same reference
    // so both arr and temp now contain { "blah", "blah", "blah" }
}

这是因为您实际上返回的是一个全新的对象,而不是修改现有对象上的条目。如果要指定新对象,则应使用
out

下面的示例显示了
out
ref
和常规传递如何在数组arg上工作。如您所见,无论是否指定了
ref
,数组都是通过引用传递的;但是,如果返回一个全新的对象,则需要指定
out

class Program
{
    static void Main(string[] args)
    {
        string[] val;
        foo(out val);
        Console.WriteLine(string.Join(",", val));
        // Output: 1, 2

        bar(ref val);
        Console.WriteLine(string.Join(",", val));
        // Output: modified, 2

        bar2(val);
        Console.WriteLine(string.Join(",", val));
        // Output: modified again, 2

        Console.Read();
    }

    static void foo(out string[] temp)
    {
        temp = new string[]{"1", "2"};
    }

    static void bar(ref string[] temp)
    {
        temp[0] = "modified";
    }

    static void bar2(string[] temp)
    {
        temp[0] = "modified again";
    }
}

这是因为您实际上返回的是一个全新的对象,而不是修改现有对象上的条目。如果要指定新对象,则应使用
out

下面的示例显示了
out
ref
和常规传递如何在数组arg上工作。如您所见,无论是否指定了
ref
,数组都是通过引用传递的;但是,如果返回一个全新的对象,则需要指定
out

class Program
{
    static void Main(string[] args)
    {
        string[] val;
        foo(out val);
        Console.WriteLine(string.Join(",", val));
        // Output: 1, 2

        bar(ref val);
        Console.WriteLine(string.Join(",", val));
        // Output: modified, 2

        bar2(val);
        Console.WriteLine(string.Join(",", val));
        // Output: modified again, 2

        Console.Read();
    }

    static void foo(out string[] temp)
    {
        temp = new string[]{"1", "2"};
    }

    static void bar(ref string[] temp)
    {
        temp[0] = "modified";
    }

    static void bar2(string[] temp)
    {
        temp[0] = "modified again";
    }
}

如果没有
ref
,对数组的引用只需复制并传递给方法(通过值-因为引用类型的void foo (string[] temp) // create a copy of a reference to the string array { temp[0] = "Boom"; // temp still points to the same object } ------------- string[] temp = new [] {"one", "two", "three"}; //outer variable foo(temp); // behind the scene we have two variables pointing to the same array foreach (string s in temp) System.Console.WriteLine(s);
    //function definition 
    void foo (ref string[] temp)  
    {
        if(temp == null)
        {
            temp = new string[] { "Hello World ", "You must be updated now" };
        }
        else
        { 
             // do something with the existing temp
        }
    } 
        string[] temp = null;
        foo(ref temp);

        foreach (string s in temp)
            System.Console.WriteLine(s);
    //function definition 
    void foo (ref string[] temp)  
    {
        temp = new string[] { "Hello World ", "You must be updated now" };
    }