C# 中 ref、out 和 in 关键字的用法是什么?

C# 中 ref、out 和 in 关键字的用法是什么?

在C#中,大多数方法可以具有零个或多个参数,这些参数定义了必须提供给方法的数据。调用方法的任何代码都必须将数据(称为参数)传递给该方法。方法将其输入声明为参数,并且它们由调用代码以参数的形式提供。

例如,考虑以下方法和随后的方法调用。

  1. static void Greet(string greeting){   Console.WriteLine(greeting);}...Greet("Hello");

登录后复制

在上面的示例中,greeting是Greet()方法的参数,而”Hello”是传递给该方法的参数。

当调用一个方法并传递参数时,它们是按值传递的,这意味着在传递给方法时会创建一个值的副本。在方法内部对参数所做的任何更改都不会反映在原始变量上。

  1. using System;int number = 8;Increase(number);Console.WriteLine(number); // prints 8static void Increase(int num){   num = num + 1;   Console.WriteLine(num); // prints 9}

登录后复制

当您传递引用类型变量(例如对象)时,C# 仍然按值复制引用,因为该变量保存的是引用,而不是实际的对象。因此,即使传递了引用变量的副本,它们也都引用了内存中的同一个对象。因此,方法内部的变量对对象所做的任何更改对于方法外部的变量都是可见的。

  1. using System;var john = new User{   Name = "John",   Salary = 50000};Promote(john);Console.WriteLine(john.Salary); // prints 60000static void Promote(User u){   u.Salary += 10000;   Console.WriteLine(u.Salary); // prints 60000}

登录后复制

但是,如果您在方法内部更改变量的值本身,则该更改不会反映在方法外部,因为仅更改了副本,而不是实际对象。例如,我们可以在方法内部将参数赋值为null,而实际变量将保持不变。

  1. using System;var john = new User{   Name = "John",   Salary = 50000};Promote(john);Console.WriteLine(john.Salary); // prints 50000static void Promote(User u){   u = null;}

登录后复制

C#允许使用三个不同的修饰符关键字来控制方法的参数。

ref修饰符

C#允许您使用ref修饰符通过引用传递参数。无论要传递的变量属于引用类型还是值类型,都不重要。参数和参数将引用相同的内存位置。

在下面的示例中,将参数u设置为null也将使john变量为null,从而引发空引用异常。

示例

  1. using System;var john = new User{   Name = "John",   Salary = 50000};Promote(ref john);Console.WriteLine(john.Salary); // throws System.NullReferenceExceptionstatic void Promote(ref User u){   u = null;}

登录后复制

使用ref修饰符传递的参数必须在传递之前进行初始化。

out修饰符

它与ref修饰符类似,除了:

参数在进入函数之前不需要进行初始化

参数在从函数中出来之前必须进行初始化(赋值)

在下面的示例中,Hire函数通过out修饰符初始化了一个传递给它的新用户对象。请注意,在调用Hire方法时,变量john是即时声明的。

  1. using System;Hire(out User john);Console.WriteLine(john.Salary); // prints 50000static void Hire(out User u){   u = new User{      Name = "John",      Salary = 50000   };}

登录后复制

ref修饰符一样,由out修饰符标记的变量通过引用传递。

通常是out > 变量用于从函数获取多个返回值,如下 –

  1. using System;var john = new User{   Name = "John",   Salary = 50000};bool shouldPromote = Raise(john.Salary, out double hike);Console.WriteLine(shouldPromote); // TrueConsole.WriteLine($"Hike Amount = {hike}"); // prints 5000static bool Raise(int salary, out double hike){   hike = salary * 0.1;   return hike

    in修饰符

    它类似于refout参数,但不同的是接受in参数的方法不能修改该参数的值。如果尝试修改,C#编译器会生成编译时错误。

    in参数可以避免将大型值类型的内存复制到参数变量中,同时防止对象被意外修改。这在将大型值类型传递给方法时非常有用。

    var point = new Coord();Verify(point);static void Verify(in Coord c){   // error: Cannot assign to variable 'in Coord' because it is a readonly variable   c = new Coord();}struct Coord{   public int X;   public int Y;}
  2. 登录后复制

  3. 示例

  4.  实时演示

  5. using System;class Program{   static void Main(){      int number = 8;      Increase(number);      Console.WriteLine(number); // prints 8      var john = new User { Name = "John", Salary = 50000 };      Promote(john);      Console.WriteLine(john.Salary); // prints 60000      Leave(john);      Console.WriteLine(john.Salary); // prints 60000      LeaveByRef(ref john);      Console.WriteLine(john?.Salary); // prints nothing      User dave;      Hire(out dave);      Console.WriteLine(dave.Salary); // prints 50000   }   static void Increase(int num){      num = num + 1;      Console.WriteLine(num); // prints 9   }   static void Promote(User u){      u.Salary += 10000;      Console.WriteLine(u.Salary); // prints 60000   }   static void Leave(User u){      u = null;   }   static void LeaveByRef(ref User u){      u = null;   }   static void Hire(out User u){      u = new User{         Name = "John",         Salary = 50000      };     }}class User{   public string Name { get; set; }   public int Salary { get; set; }}
  6. 登录后复制

  7. 输出

  8. 9860000600006000050000
  9. 登录后复制

  10. 以上就是C# 中 ref、out 和 in 关键字的用法是什么?的详细内容,更多请关注【创想鸟】其它相关文章!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

点点赞赏,手留余香

给TA打赏
共0人
还没有人赞赏,快来当第一个赞赏的人吧!
    编程技术

    C# 接口类型

    2025-3-3 7:36:06

    编程技术

    将文本附加到现有文件的 C# 程序

    2025-3-3 7:36:20

    0 条回复 A文章作者 M管理员
    欢迎您,新朋友,感谢参与互动!
      暂无讨论,说说你的看法吧
    个人中心
    购物车
    优惠劵
    今日签到
    私信列表
    搜索