• C#8.0本质论第五章--方法和参数


    C#8.0本质论第五章–方法和参数

    5.1方法的调用

    5.1.1命名空间

    命名空间主要用于按功能领域组织类型,以便查找和理解这些类型。此外,命名空间还有助于防范类型名称冲突。

    5.1.2类型名称
    5.1.3作用域
    5.1.4方法名称
    5.1.5形参和实参
    5.1.6方法返回值
    5.1.7对比语句和方法调用

    5.2方法的声明

    C#不支持全局方法,一切都必须在类型声明中。这正是Main方法标记为static的原因。

    5.2.1参数声明
    5.2.2方法返回类型声明

    如果方法又返回类型,它的主体必须没有“不可到达的结束点”。换言之,方法不能在不返回值的情况下碰到大括号而自然结束。

    从C#7.0开始多个值可以通过元组语法打包成元组返回。

    5.2.3表达式主体方法

    为简化方法的定义,C#6.0引入了表达式主体方法,允许用表达式代替完整方法主体。

    和C++不同C#类从来不将实现与声明分开(C#确实支持名为“分部方法”的高级功能,允许将方法的声明和实现分开)。

        static string GetFullName( string firstName, string lastName) =>
                  $"{ firstName } { lastName }";
    
    • 1
    • 2

    5.3using指令

    using指令不“导入”任何嵌套命名空间中的类型,虽然添加了using System;,但要访问System.Text中的StringBuilder类型必须添加一个using System.Text指令或对类型进行完全限定。

    在java中可以用通配符导入命名空间,但C#不允许,每个命名空间都必须显示导入。

    5.3.1using static指令
    5.3.2使用别名

    可以利用using指令为命名空间或类型取一个别名。别名的两个最常见的用途是消除两个同名类型的歧义和缩写长名称。

    5.4Main()的返回值和参数

    C#支持在执行程序时提供命令行参数,并允许从Main()方法返回状态标识符。

    5.5高级方法参数

    5.5.1值参数

    参数默认采用传值方式。

    int a=123;
    string b="456";
    ClassC c=new ClassC();
    
    func(a,b,c);
    
    func(int a,string b,ClassC c)
    {
        ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    上面的调用中,a传的是123这个数值,b传的是"456"这个字符串字面值,c传的是c指向的对象的引用(地址),也就是c这个变量的值。

    这些值传进函数里后赋值给了函数里的a,b,c,所以函数里的abc是新创建的局部变量。给c的某个成员赋值会影响外面的c,因为c都指向同一个对象。但如果给c变量new一个新对象,不会对外面的c造成影响,因为c是局部变量。字符串同理。

    5.5.2引用参数

    调用者应初始化传引用的局部变量。

    函数里的ref参数只是传递的变量的别名,换言之,引用参数的作用只是为现有变量分配参数名,而非创建新变量并将实参的值拷贝给它。

    5.5.3输出参数

    out参数功能上与ref参数完全一致,区别就是C#语言对别名变量的读写又不同规定。如参数被标记为out,编译器会核实在方法所有正常返回的代码路径中,是否都对该参数进行了赋值。

    从C#7.0起可在调用方法前以内联的形式声明out变量,而不必在使用前声明out变量。

    C#7.0的另一个功能是允许完全放弃out参数,可用下划线放弃参数:

    TryGetPhoneButton(character,out _);
    
    • 1

    C#7.0写代码时,返回两个或更多值应首选元组语法。

    5.5.4只读传引用

    C#7.2支持以传引用的方式传入只读值类型。避免了每次调用方法都创建值类型的拷贝,而且不用担心值类型参数被修改。换言之,其作用是在传值时减少拷贝量,为参数添加in修饰符。

    5.5.5返回引用

    C#7.0新增的另一个功能返回对变量的引用。

    // Returning a reference
    public static ref byte FindFirstRedEyePixel(byte[] image)
    {
        // Do fancy image detection perhaps with machine learning
        for (int counter = 0; counter < image.Length; counter++)
        {
            if (image[counter] == (byte)ConsoleColor.Red)
            {
                return ref image[counter];
            }
        }
        throw new InvalidOperationException("No pixels are red.");
    }
    public static void Main()
    {
        byte[] image = new byte[254];
        // Load image
        int index = new Random().Next(0, image.Length - 1);
        image[index] =
            (byte)ConsoleColor.Red;
        Console.WriteLine(
            $"image[{index}]={(ConsoleColor)image[index]}");
        // ...
     
        // Obtain a reference to the first red pixel
        ref byte redPixel = ref FindFirstRedEyePixel(image);
        // Update it to be Black
        redPixel = (byte)ConsoleColor.Black;
        Console.WriteLine(
            $"image[{index}]={(ConsoleColor)image[redPixel]}");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    ref局部变量被初始化为引用一个特定变量,以后不能修改为引用其他变量。(有点像C++里引用了)

    5.5.6参数数组

    要么以逗号分隔的字符串参数,要么是单个字符串数组,声明了参数数组之后,每个参数都作为参数数组的成员来访问。

    参数数组必须是最后一个,所以只能有一个。

    5.6递归

    5.7方法重载

    方法重载是一种**操作性多态(**operational polymorphism)。如由于数据变化造成同一个逻辑操作具有许多形态,就会发生多态。

    5.8可选参数

    C#4.0新增了对可选参数的支持。可选参数一点要放到所有必须参数后面。默认值必须是常量或者其他能在编译时确定的值。

    C#4.0新增的另一个方法调用功能是具名参数

    public static void Main()
    {
        DisplayGreeting(
            firstName: "Inigo", lastName: "Montoya");
    }
     
    public static void DisplayGreeting(
        string firstName,
        string? middleName = null,
        string? lastName = null
        )
    {
        // ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    如果一个方法有大量参数,许多都可选,那么具名参数语法肯定能带来不少遍历,但代价是牺牲了方法接口的灵活性,参数名变成了方法接口的一部分。

    假如由于其中一个方法有可选参数使得两个方法都适用,编译器最终将选择无可选参数的方法。

    5.9用异常实现基本错误处理

    5.9.1捕捉错误
    5.9.2使用throw语句报告错误
  • 相关阅读:
    点云从入门到精通技术详解100篇-基于深度学习的3D点云焊点缺陷检测
    Uboot spi-nor 设备信息定义及3地址模式和4地址模式的理解
    c语言通信之串口通信
    java计算机毕业设计springboot+vue专业手语翻译预约系统
    Bevy的一些窗口设置
    BATJ 互联网公司面试必问知识点:Spring 全家桶全解,java 分布式框架技术方案
    Springboot 集成 nacos (小白已测)
    background-repeat
    form表单以及CSS
    【单片机】msp430g2553单片机, 用TA0定时器,让小灯P1.6呼吸灯,P1.6是TA0.1
  • 原文地址:https://blog.csdn.net/Story_1419/article/details/132872208