简体   繁体   English

函数中类参数之间的差异

[英]difference between class parameter in function

I wrote this code in visual studio. 我在Visual Studio中编写了这段代码。

public class Class1
 {
    public string MySTR;
 }


private static void func1(Class1 class )
 {
  class = new Class1();
  class.MySTR = "B";
 }

private static void func2(Class1 class )
{
  class.MySTR = "C";
}

static void Main(string[] args) 
{       
  Class1 class = new Class1();
  class.MySTR = "A";
  func1(class);
  Console.WriteLine(class.MySTR);
  func2(ref class);
  Console.WriteLine(class.MySTR);
}

I expected to get AA but I got AC. 我本来希望获得AA,但是我获得了AC。

What the difference between these methods? 这些方法之间有什么区别?

Thank you. 谢谢。

class is refrence type ok this code return "B" 类别是参考类型,确定此代码返回“ B”

using System;
namespace ConsoleApplication2
{
    public class Class1
    {
        public string MySTR;
    }
    class Program
    {
        private static void func1(Class1 c )
         {
          //c = new Class1();
          c.MySTR = "B";
         }

        private static void func2(Class1 c )
        {
          c.MySTR = "C";
        }

        static void Main(string[] args) 
        {       
          Class1  c = new Class1();
          c.MySTR = "A";
          func1(c);
          Console.WriteLine(c.MySTR);
          //func2(ref c);Error
          //Console.WriteLine(c.MySTR);
          Console.ReadKey();
        }
    }
}

Why you expect to get "AA" ? 为什么您期望获得"AA" "AC" is correct output. "AC"是正确的输出。 Check comments in following code blocks (codes has been modified slightly to make it compile and run) : 检查以下代码块中的注释(对代码进行了一些小的修改以使其可以编译和运行):

private static void func1(Class1 class1)
{
    //create new instance of Class1
    class1 = new Class1();
    //modify the new instance. 
    //Original instance passed to method parameter remain untouched
    //Hence you still got "A" from 1st Console.WriteLine(class1.MySTR);
    class1.MySTR = "B";
}

private static void func2(Class1 class1)
{
    //modify Class1 instance passed to method parameter. 
    //It's MySTR member value becomes "C" after this
    //Hence you got "C" from 2nd Console.WriteLine(class1.MySTR);
    class1.MySTR = "C";
}

static void Main(string[] args)
{
    Class1 class1 = new Class1();
    class1.MySTR = "A";
    func1(class1);
    Console.WriteLine(class1.MySTR);
    func2(class1);
    Console.WriteLine(class1.MySTR);
}

Yes it's correct, 是的,这是正确的,

When you passed by ref it will pass by the address and update the value on that address so how it works. 当您通过ref传递时,它将传递地址并更新该地址上的值,以便其工作。

First you have created a object so object has been created on heap and one address is assigned to that object and you have assigned a MySTR="A" so now the value of MySTR is A now you called the function 1 so it will go into function 1 with MySTR="A" now over there you have a reinitialize that object so one another object is being created on different address and you have assigned the value of MySTR="B" now you tried to print cl.MySTR where the value A is already store so first output is A 首先,您创建了一个对象,因此在堆上创建了一个对象,并为该对象分配了一个地址,并分配了MySTR =“ A”,因此,现在MySTR的值为A,现在您调用了函数1,它将进入带有MySTR =“ A”的函数1,您在那里重新初始化了该对象,因此在不同的地址上创建了另一个对象,并且您已经分配了MySTR =“ B”的值,现在您尝试打印cl.MySTR,其中该值A已经存储,所以第一个输出是A

in second part you have passed the address of that object and tried to changed the value in same object so it would be C. 在第二部分中,您已经传递了该对象的地址,并尝试更改同一对象中的值,因此它将是C。

you code should be look like 您的代码应该看起来像

class Program 班级计划

{ {

    static void Main(string[] args)
    {
        Class1 cl = new Class1();
        cl.MySTR = "A";
        func1(cl);
        Console.WriteLine(cl.MySTR);
         func2(ref cl);
         Console.WriteLine(cl.MySTR);
         Console.ReadLine();
    }

    private static void func1(Class1 cla)
    {
        cla = new Class1();
        cla.MySTR = "B";
    }
    private static void func2(ref Class1 clas)
    {
        clas.MySTR = "C";
    }
}
public class Class1
{
    public string MySTR;

}

har07 has it right. har07正确。

To clarify further, reference types (such as classes) are always passed by reference in C#. 为了进一步说明,引用类型(例如类)始终在C#中通过引用传递。 I assume you're coming from C(++) background, so imagine that the function is actually func2(Class1 *class1) . 我假设您来自C(++)背景,因此可以想象该函数实际上是func2(Class1 *class1)

The ref keyword (which has to be in both the method and its call, no mixing) will pass the reference by reference, ie. ref关键字(必须同时存在于方法及其调用中,不能混用)将按引用传递引用,即。 func2(Class1 **class1) . func2(Class1 **class1) This allows you to return a new instance (the way you perhaps tried to do so in func1 ). 这允许您返回一个新实例(您可能在func1尝试这样做的方式)。

Structs and other value types, on the other hand, are by default passed by value, ie. 另一方面,结构和其他值类型默认情况下按值传递,即。 func(Struct1 s) . func(Struct1 s) Using ref with structures is trickier, but effectively it mostly works like func(Struct1 **s) , ie. ref与结构一起使用会比较棘手,但实际上,它大多数都可以像func(Struct1 **s)一样工作。 you can assign values to the struct fields, and you can pass back a whole new struct "instance". 您可以将值分配给struct字段,并且可以传回全新的结构“实例”。

Another "reference by reference" variant is the out keyword, which is something like a promise to the caller - you don't pass an existing reference, but the callee has to pass a reference back: 另一个“按引用引用”变体是out关键字,它类似于对调用方的承诺-您不会传递现有引用,但是被调用方必须将引用传递回去:

void DoStuff(out int num)
{
  num = 23;
}

void SomeOtherFunction()
{
  int myNum;

  DoStuff(out myNum);

  // myNum now contains the value 23
}

The value myNum has before the call doesn't matter (in my sample, the variable is actually "undefined" - passing it by ref or by value would cause a compiler error), and the callee ( DoStuff ) must assign all its out parameters before returning. myNum在调用之前具有的值无关紧要(在我的示例中,变量实际上是“未定义”的-通过ref或按值传递它会导致编译器错误),并且被调用方( DoStuff必须分配其所有out参数返回之前。

The 2 methods are declared as static which means they are instance-independant . 这两个方法被声明为static ,这意味着它们是实例无关的 If you change them in func1 it is changed across all the instances of Class1 如果您在func1中更改它们,则将在Class1所有实例中更改它们

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 泛型函数和带有Type参数的函数之间的区别 - Difference between generic function and function with Type parameter 通用声明和提供类参数之间的区别 - Difference between generic declaration and providing class parameter 受继承限制的泛型方法和基类参数之间有什么区别? - What is the difference between a generic method limited by inheritance and a base class parameter? 使用抽象类作为方法参数和约束到所述抽象类的泛型参数之间是否有任何明显的区别? - Is there any appreciable difference between using an abstract class as a method parameter and generic parameter constrained to said abstract class? 将类传递给函数或带有引用的结构之间的功能区别是什么? - What is the functional difference between passing a class to a function, or a struct with a reference? 两个参数分配之间的差异 - Difference between the both parameter assignment 将匿名函数与Func / Action发送给具有Delegate参数的另一个函数之间的区别? - Difference between sending an anonymous function vs. Func/Action to another function with a Delegate parameter? 这两个函数调用之间的区别 - Difference between these 2 function calls 对象参数和通用参数(类型参数)之间的差异 - difference between object parameter and generic parameter(type parameter) 类和数据类型有什么区别? - What is the difference between a class and a datatype?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM