Zhonghui

每个不曾起舞的日子,都是对生命的辜负

User Tools

Site Tools


程序:csharp:函数

C#函数小技巧


参数:传值还是传引用

参考:数据类型

参数修饰符

in / out / ref / params

直接上代码:

示例代码

using System.Collections.Generic;
 
namespace Zhonghui
{ 
    class MainApp
    {
        // 先上总结
        // 1.in 相当于传递进来的变量是只读的
        // 2.out 可以读取,必须写入
        // 3.ref 相当于C++的引用类型参数
        // 4.params 可变数量的参数
 
        // 不适用任何修饰符号,表现就不赘述了
        // 复习一下:形参和实参
 
        // 使用in
        // 这里传递了一个引用类型,在函数内部也是可以操作的
        static void F1(in List<int> Data)
        {
            Data.Add(10); // 可以操作,所造成的变更也是影响到外部的
 
            // Data = null; // 错误
            // 但是不能对其进行赋值
        }
 
        // 使用in
        // 传递值类型,就完全不能操作了
        static void F2(in int Data)
        {
            // Data = 10; // 错误
            // 禁止进行赋值
        }
 
        // 使用out
        // 传递一个值类型,函数内部的修改也会影响到外部
        static void F3(out int Data)
        {
            // 对其进行的修改也是影响到函数外部的
            Data = 3; // 函数内部必须对这个参数进行修改,否则就是语法错误
 
            // out的参数并不是只写的,也是可以正常读取的
            int Local = Data;
        }
 
        // 使用ref
        // 引用类型参数,即使传递的是一个值类型
        static void F4(ref int Data)
        {
            int Local = Data; // 读取是正常的
 
            Data = 4; // 可以对参数进行修改,并且修改会影响到函数外部
 
            // 读写都不是强制进行的
        }
 
        // 使用params
        // 可变数量的参数,但是类型要相同,后面的参数会一起放到一个数组里面
        // 一个函数的参数列表中,只能有一个params,且params必须在最后
        static void F5(bool NeedPrint, params int[] Numbers)
        {
            int Sum = 0, Count = 0;
            foreach (int Number in Numbers)
            {
                Sum += Number;
                Count += 1;
            }
 
            if(NeedPrint)
            {
                Console.WriteLine("Count = " + Count.ToString() + "; Sum = " + Sum.ToString());
            }
        }
 
        static void Main()
        {
            List<int> Data = new List<int>();
            for (int i = 0; i < 4; i += 1)
            {
                Data.Add(i);
            }
            Print(Data);
 
            F1(Data); // 调用的时候不需要使用in修饰符,当然加上in也是可以的
            Print(Data); // 使用in传递的参数,但是修改也生效了,因为是引用类型的变量
 
            F2(0); // 传递进去一个常量,这里调用的时候不能使用in修饰符,查一下为什么
 
            int IntData; // 使用out修饰符传入的参数,不需要提前初始化
            F3(out IntData); // 调用的时候也必须使用out修饰符
            // 修改是影响到外部的
            Console.WriteLine("Data = " + IntData.ToString());
 
            F4(ref IntData); // 调用的时候也必须使用ref修饰符
            Console.WriteLine("Data = " + IntData.ToString());
 
            // int Nothing; // 一个没有初始化的变量
            // F4(ref Nothing); // 错误:禁止使用ref修饰符传入没有初始化的变量
            // 使用ref的参数必须提前初始化,这是和out不同的地方
 
            // 以上out和ref在调用的时候也必须使用修饰符,我感觉原因是:
            // 因为函数可能(或者必须)修改参数,所以函数的调用方必须明确指出这一点
            // 明确自己是知道这个影响的,允许函数修改我传递进去的参数
 
            // 可变数量的参数
            F5(true, 1, 2, 3, 4, 5); // 后面对应的自动变成数组
 
            int[] ArrayData = new int[] { 1, 2, 3 };
            F5(true, ArrayData); // 直接传递一个数组也是可以的
 
            // 但是这样混用是错误的
            // F5(true, ArrayData, 100);
        }
 
        static void Print(List<int> Data)
        {
            Console.WriteLine("Print Data, Length = " + Data.Count.ToString());
            for (int i = 0; i < Data.Count; i += 1)
            {
                Console.Write(Data[i].ToString() + " ,");
            }
            Console.WriteLine();
        }
    }
}

out的一个小技巧

class Application
{
    static void GetLuckyNumber(out int Result)
    {
        Result = 10;
    }
 
    static void Main()
    {
        // 可以直接在这里声明变量
        GetLuckyNumber(out int luckyNumber);
 
        Console.WriteLine(luckyNumber.ToString());
    }
}
/var/www/DokuWikiStick/dokuwiki/data/pages/程序/csharp/函数.txt · Last modified: 2022/11/23 08:09 by zh