Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.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# 在将值类型传递给C中的方法时更改该值类型#_C#_Methods_Parameter Passing_Value Type - Fatal编程技术网

C# 在将值类型传递给C中的方法时更改该值类型#

C# 在将值类型传递给C中的方法时更改该值类型#,c#,methods,parameter-passing,value-type,C#,Methods,Parameter Passing,Value Type,关于C#的基本手册规定,要在传递给另一种方法时更改值类型,必须使用out或ref关键字等 例如: int Loop(int counter) { return(++counter); } void ClickIt () { int count = 0; for (int c1 = 0; c1 < 10; c1++) { count = Loop(count); Console.Writeline(count); }

关于C#的基本手册规定,要在传递给另一种方法时更改值类型,必须使用
out
ref
关键字等

例如:

int Loop(int counter)
{
   return(++counter);
}

void ClickIt ()
{
    int count = 0;
    for (int c1 = 0; c1 < 10; c1++) 
    {
        count = Loop(count);
        Console.Writeline(count);
    }
}
int循环(int计数器)
{
返回(++计数器);
}
作废点击它()
{
整数计数=0;
对于(int c1=0;c1<10;c1++)
{
计数=循环(计数);
控制台写入线(计数);
}
}
在这里,
单击它
输出以下结果:
1,2,3,4。。。10

在本例中,
count
(一种值类型),它从方法
点击它
传递到方法
循环
,不带
out
ref
,在
循环
中更改。然后
循环
计数
返回到调用方法
单击它
,它将拾取对
计数
的更改


所以,我的问题是:当一个值类型作为参数传递给另一个方法时,需要使用
out
ref
才能更改该值吗?

在您的示例中,您实际上没有修改传递的计数变量。 传递时,将在循环函数范围内创建一个副本。修改完成后,返回并设置为count变量

实际上,目的是:

  • ref-是指变量在传递到函数之前应该已经初始化。而副本不是在内部创建的。您可以直接修改传递的变量。因此,您不需要返回修改后的值并将其设置回变量
  • out-在传递到函数之前,不需要初始化传递的变量。但它实际上必须在该函数内初始化
  • 希望就这些。

    长篇评论。。。 您的代码可能会混淆-请确保将函数的结果与参数分开:

    void ClickIt ()
    {
        int count =0;
        for (int c1 =0; c1 < 10; c1++) 
        {
            var resultCount = Loop(count);
            Console.Writeline("Result:{0}, count:{1}", resultCount, count);
        }
    }
    
    void单击它()
    {
    整数计数=0;
    对于(int c1=0;c1<10;c1++)
    {
    var resultCount=循环(计数);
    Writeline(“结果:{0},计数:{1}”,结果计数,计数);
    }
    }
    
    答案(基于意见)-您几乎不应该使用
    out
    /
    ref
    -这比返回值更难推理。由于需要将参数作为变量,因此在LINQ/lambda表达式中也很难使用此类函数


    一般情况下,当函数返回不止一个结果时(如<代码> TyPARSE ),但是考虑其他返回类型(即空值<代码> INT/<代码>)是否会起作用。

    < P>您对“REF”的含义有不正确的理解,并且您还混合了值和变量。这些都是常见的错误

    让我们回到基础上来

    变量是可以包含值的存储位置

    让我们简化您的程序:

    int M(int x)
    {
        x++;
        return x;
    }
    void N()
    {
        int y = 0;
        y = M(y);
    }
    
    如果调用N,会发生什么

    假设一个变量是一个抽屉,里面可以放一张纸。我们做一个抽屉,贴上y的标签。在y中,我们放了一张写着“0”的纸。现在我们称之为M(y)。会发生什么

    我们制作了一个标有“x”的新抽屉,并用“y”复印了这张纸。我们把副本放在x号抽屉里。y包含一张纸,上面写着0,而x包含另一张纸,上面也写着0

    现在在M中,我们增加x。会发生什么?我们做了一张写着1的新纸,扔掉旧的,把新的放在抽屉x里

    现在我们复印一份x的值,所以我们有另一张纸,上面写着1。当M返回时,我们把那张纸放进y中,扔掉已经在那里的0

    我修改了你的名字吗?不,M只修改了x。是的,两次。在创建y时返回一次,在M之后返回一次

    请注意,我们复制了两份。首先,我们在进入M的过程中复制了一个y,并将其复制到x,然后在离开的过程中复制了一个x,并将其复制到y

    现在假设我们有

    void P(ref int b)
    {
       b++;
    }
    void Q()
    {
        int c = 0;
        P(ref c);
    }
    
    我们运行Q。会发生什么?我们制作了一个名为c的抽屉,里面放了一张写着“0”的纸。当我们叫P时会发生什么?有些不同。这次我们制作了一个名为b的抽屉,在里面放了一张纸,上面写着“不要使用这个抽屉!每次你尝试使用这个抽屉时,用c来代替!”也就是说,b将其行为指向c

    现在p试图增加b。它试图从b中得到一个值,但发现b说不,使用c。它在c中查找,找到0,制作一张新的纸,上面写着1,替换了b的内容——不,等等,我们需要用1替换c的内容,然后返回。所以c被更新为1


    为什么这两件事是不同的,这有道理吗?第一个被称为“复制入,复制出”,因为我们在进入M的过程中复制了一份y,在离开M的过程中复制了一份x。第二个通过引用称为,因为b将其行为指向c;不复制任何值。

    对象通过ref传递,对于结构和基本数据类型,除非指定out或ref,否则通过val传递。更改不会通过
    循环的参数传回。由于显式分配了
    循环
    的返回值,因此更改会写入
    计数
    变量。