ref,out,int参数复习

ref

结构是值类型,按值传递。通过关键字ref,也可以通过引用传递结构。

public static void ChangeA(ref A a)
{
a.X
= 2; } //如果A是结构类型,就添加ref修饰符,修改ChangeA方法的声明,通过引用传递变量

在Main函授中执行,按照引用传递,所以结果是2。

A a1 = new A {X =1};
ChangeA(ref a1);
Console.WriteLine(a1.X);
//给方法参数应用了ref修饰符后,在调用方法时需要添加它。

使用ref后,也可以传递对引用的引用(在C++术语中,是一个指向指针的指针),它允许分配一个新对象。

public static void ChangeA(A a)
{
    a.X = 2;
    a = new A {X = 3};//这一行在堆栈上创建了一个新对象,和一个对新对象的引用。Main()方法中使用的变量a1仍然引用值为1的旧对象。ChangeA方法结束后,没有引用堆栈上的新对象,可以回收它。所以这里的Main()方法里输出结果仍然是1.
//添加ref修饰符后,传递对引用的引用,允许分配新对象,此时Main()方法里,输出结果是3.
public static void ChangeA(ref A a)
{
  a.X = 2;
  a = new A {X = 3};
}

完整代码

 

using System;

namespace refDemo
{
    class Program
    {
        static void Main(string[] args)
        {
        //Console.WriteLine("Hello World!");
        A a1 = new A{X = 1};
        //ChangeA(ref a1);
        ChangeANotRef(ref a1);
        System.Console.WriteLine($"{a1.X.ToString()}");
        }
        private static void ChangeA(ref A a)
            {
                a.X = 2;
            }
            private static void ChangeANotRef(ref A a)
            {
                a.X = 2;
                a = new A{X = 3};
            }
    }
    struct  A
    {
        public int X;
    }
}
    
    

 

out

如果方法返回一个值,该方法通常声明返回类型,并返回结果。如果方法返回多个值,可能类型还不同,这有不同的选项去处理。一个选项是声明类和结构,把应该返回的所有信息都定义为该类型的成员。另一个选项是使用元组类型。第三个选项是使用out关键字。

if(int.TryParse(Console.ReadLine(),out int num))
{
   //to do;
}
//返回一个bool值,当用户输入的字符串可以转换为Int32时,返回true,反之为false.

若方法已明确定义返回类型,则也可以用关键字var代替int.

in

C#7.2向参数添加了in修饰符。out修饰符允许返回参数指定的值。in修饰符保证发送到方法中的数据不会更改(在传递值类型时)。

下面定义一个简单的可变结构体,再定义一个公共可变字段。

struct AValueType
{
 public int Data;
}

此时,使用in修饰符定义一个方法时,变量就不能更改了。试图更改可变字段Data,编译器会报错,不能为只读变量的成员分配值。in修饰符使参数设置为只读变量。

static void CantChange(in AValueType a)
{
  //a.Data = 43;//does not compile - readonly variable
  Console.WriteLine(a.Data);
}

使用in修饰符,不仅有助于确保不更改内存,编译器还可以创建更好的优化代码。与使用方法调用来复制值类型不同,编译器可以使用引用,从而减少所需内存并提高性能。

注:in修饰符主要用于值类型,也可以对引用类型使用它。in修饰符用于引用类型时,可以更改该引用类型变量的成员内容(如公共属性),但不能更改变量本身。

 

using System;

namespace refDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            TestChangeStr(new TestClass());
        }
        private static void TestChangeStr(in TestClass test)
        {
            test.Str = "Str";
            //test = new TestClass();//error
            System.Console.WriteLine(test.Str);
        }
    }
    class TestClass
    {
        public string Str;
    }
}

 

posted @ 2019-11-24 17:18  singhwong  阅读(314)  评论(0编辑  收藏  举报