C#(四):构造函数、返回值类型、重载、函数参数、ref、out、partial、属性、访问器、索引器、委托

构造函数

使用默认字面量设置字段

internal class Program
{
    
    
    static void Main(string[] args)
    {
    
    
        Person person1 = new Person("Lee", null);
        person1.say(); // Lee ---> 0
        Person person2 = new Person("Lee", 18);
        person2.say(); // Lee ---> 18
    }
}

class Person
{
    
    
    private string name;
    private int age;

    public Person(string name, int? age)
    {
    
    
        this.name = name;
        this.age = age ?? default; // this.age = age ?? default(int);
    }

    public void say() {
    
    
        Console.WriteLine($"{
      
      this.name} ---> {
      
      this.age}");
    }
}

构造函数重复定义赋值问题解决

  • 在调用构造方法之前查找其他构造方法先行调用
  • 在构造Person(string name, int age, char sex)方法时先行调用Person(string name)方法
class Person
{
    
    

    string Name;
    int Age;
    char Sex;

    public Person(string name) {
    
    
        Name = name;
    }

    //public Person(string name, int age, char sex)
    //{
    
    
    //    Name = name; // 重复定义
    //    Age = age;
    //    Sex = sex;
    //}

    // 修改重复定义方法
    public Person(string name, int age, char sex) : this(name)
    {
    
    
        Age = age;
        Sex = sex;
    }

}

Person person = new Person("Lee", 23, '1');

静态构造函数

  • 不允许使用访问权限修饰符
  • 不允许存在参数
  • 在第一次使用这个类的时候执行(当类被加载到内存中的时候执行), 再次实例化不会被调用
class MainClass
{
    
    

    public static void Main(string[] args)
    {
    
    

        // 解决打印中文乱码问题
        Console.OutputEncoding = System.Text.Encoding.UTF8;

        new Person(); // 静态构造方法被执行 非静态构造方法被执行

        new Person(); // 非静态构造方法被执行

    }

}


class Person
{
    
    

    static Person() {
    
    
        Console.WriteLine("静态构造方法被执行");
    }

    public Person() {
    
    
        Console.WriteLine("非静态构造方法被执行");
    }

}

函数返回值类型

internal class Program
{
    
    
    static void Main(string[] args)
    {
    
    
        Person person = new Person("Lee", 18);

        Console.WriteLine(person.GetName()); // Lee
        Console.WriteLine(person.GetAge());  // 18

        (string, int) info1 = person.GetInfo();
        Console.WriteLine(info1); // (Lee, 18)
        Console.WriteLine($"{
      
      info1.Item1} ---> {
      
      info1.Item2}"); // Lee ---> 18

        (string Name, int Age) info2 = person.GetInfo();
        Console.WriteLine(info2); // (Lee, 18)
        Console.WriteLine($"{
      
      info2.Name} ---> {
      
      info2.Age}"); // Lee ---> 18

        // 解构元组赋值
        (string name, int age) = person.GetInfo();
        Console.WriteLine($"{
      
      name} ---> {
      
      age}"); // Lee ---> 18
    }
}

class Person
{
    
    
    private string name;
    private int age;

    public Person(string name, int age)
    {
    
    
        this.name = name;
        this.age = age;
    }

    // 返回字符串
    public string GetName()
    {
    
    
        return name;
    }

    // 返回int类型
    public int GetAge()
    {
    
    
        return age;
    }

    // 返回(string, int)元组
    // 或者 (string Name, int Age) return (Name: name, Age: age)
    public (string, int) GetInfo()
    {
    
    
        return (name, age);
    }
}

重载

构造函数重载

internal class Program
{
    
    
    static void Main(string[] args)
    {
    
    
        new Person();                       // 无参构造函数
        new Person("Lee");                  // Lee
        new Person(18);                     // 18
        new Person("Lee", 18);              // Lee: 18
        new Person(18, "Tom");              // 18: Tom
        new Person("Tom", 18, Sex.male);    // Tom: 18--->male
    }
}

enum Sex
{
    
    
    male, female
}

class Person
{
    
    

    public Person()
    {
    
    
        Console.WriteLine("无参构造函数");
    }

    public Person(string name) 
    {
    
    
        Console.WriteLine($"{
      
      name}");
    }
    public Person(int age)
    {
    
    
        Console.WriteLine($"{
      
      age}");
    }

    public Person(string name, int age)
    {
    
    
        Console.WriteLine($"{
      
      name}: {
      
      age}");
    }

    public Person(int age, string name)
    {
    
    
        Console.WriteLine($"{
      
      age}: {
      
      name}");
    }

    public Person(string name, int age, Sex sex)
    {
    
    
        Console.WriteLine($"{
      
      name}: {
      
      age} ---> {
      
      sex}");
    }
}

一般函数重载

internal class Program
{
    
    
    static void Main(string[] args)
    {
    
    
        Person person = new Person("Tom", 20, Sex.female);
        person.say();               // Tom 20 female
        person.say("Lee", 18);      // Lee 18 female --返回--> Lee
    }
}

enum Sex
{
    
    
    male, female
}

class Person
{
    
    
    string name;
    int age;
    Sex sex;

    public Person(string name, int age, Sex sex)
    {
    
    
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public void say()
    {
    
    
        Console.WriteLine($"{
      
      name} {
      
      age} {
      
      sex}");
    }

    // 重载方法与有无返回值无关
    public string say(string name, int age)
    {
    
    
        Console.WriteLine($"{
      
      name} {
      
      age} {
      
      sex}");
        return name;
    }
}

可选参数命名参数

internal class Program
{
    
    
    static void Main(string[] args)
    {
    
    
        Person person = new Person();

        // 可选参数
        person.GetInfo("Tom", 20, "男"); // Tom 20 男
        person.GetInfo("Lee", 25); // Lee 25 男

        // 命名参数
        person.GetInfo(name: "Tom", age: 20, sex: "男"); // Tom 20 男
        person.GetInfo(age: 20, sex: "男", name: "Tom"); // Tom 20 男
    }
}

class Person
{
    
    
    // 可选参数
    public void GetInfo(string name, int age = 18, string sex = "男")
    {
    
    
        Console.WriteLine($"{
      
      name} {
      
      age} {
      
      sex}");
    }
}

refout

  • ref
    • 用来修饰参数
    • 如果一个形参用ref修饰,那么实参也需要用ref修饰
    • a的改变是因为用ref修饰的参数最终传的是实参的地址
    public static void Change(ref int x) {
          
          
        x = 20;
    }
    
    int a = 10;
    Change(ref a);
    Console.WriteLine(a); // 20
    
  • out
    • 用来修饰参数
    • 如果一个形参用out修饰,那么实参也需要用out修饰
    • a的改变是因为用out修饰的参数最终传的是实参的地址
    public static void Change(out int x)
    {
          
          
        x = 20;
    }
    
    Change(out int a);
    Console.WriteLine(a);
    
  • 区别
    • 在方法结束之前必须对out参数赋值
      public static void Change(out int x) {
              
               } // Error 没有对参数x进行赋值
      
    • ref参数可以直接使用,而out参数需要进行赋值后才能使用(ref参数默认被赋值了而out参数默认没有被赋值
      public static void Change(ref int x)
      {
              
              
          Console.WriteLine(x); // ok
      }
      
      public static void Change(out int x)
      {
              
              
          Console.WriteLine(x); // Error 使用了未赋值的变量x
          x = 20;
          Console.WriteLine(x); // ok
      }
      

partial

partial

internal class Program
{
    
    
    static void Main(string[] args)
    {
    
    
        Person person = new Person();
        person.SayInfo("Tom", 20, "男"); // Tom 20 男
        person.SayName("Lee"); // Lee
    }
}

partial class Person
{
    
    
    public void SayInfo(string name, int age, string sex)
    {
    
    
        Console.WriteLine($"{
      
      name} {
      
      age} {
      
      sex}");
    }
}

partial class Person
{
    
    
    public void SayName(string name)
    {
    
    
        Console.WriteLine($"{
      
      name}");
    }
}

partial方法

internal class Program
{
    
    
    static void Main(string[] args)
    {
    
    
        Person person = new Person();
        person.Say("abc"); // abc
    }
}

partial class Person
{
    
    
    public void Say(string text)
    {
    
    
        SayText(text);
    }

    partial void SayText(string text);
}

partial class Person
{
    
    
    partial void SayText(string text)
    {
    
    
        Console.WriteLine(text);
    }
}

属性和访问器

Person person = new Person
{
    
    
    Age = 1
};
Console.WriteLine(person.Age);

class Person
{
    
    

    private static int age;

    // Age属性
    public int Age {
    
    

        // 读 属性访问器
        get
        {
    
    
            return age;
        }

        // 写 属性访问器
        set {
    
    
            if (value <= 100)
            {
    
    
                age = value;
            }
        }

    }
}

索引器

using System;
using System.Collections.Generic;

namespace ConsoleApp
{
    
    
    internal class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            Person person = new Person();

            for (int i = 0; i <= 4; i++)
            {
    
    
                // 【get】 ---> Lee ---> 18         (Lee, 18)
                // 【get】 ---> Tom ---> 20         (Tom, 20)
                // 【get】 ---> 李四 ---> 11         (李四, 11)
                // 【get】 ---> 王五 ---> 30         (王五, 30)
                // 【get】 ---> 赵六 ---> 22         (赵六, 22)
                Console.WriteLine(person[i]);
            }

            person[1] = ("张三", 20); // 【set】 ---> Tom ---> 20

            Console.WriteLine(person[1]);       // 【get】 ---> 张三 ---> 20        (张三, 20)
            Console.WriteLine(person[1].Name);  // 【get】 ---> 张三 ---> 20        张三
            Console.WriteLine(person[1].Age);   // 【get】 ---> 张三 ---> 20        20
        }
    }

    class Person
    {
    
    
        public List<(string Name, int Age)> list = new List<(string Name, int Age)> {
    
    
            ("Lee", 18),
            ("Tom", 20),
            ("李四", 11),
            ("王五", 30),
            ("赵六", 22),
        };

        public (string Name, int Age) this[int index]
        {
    
    
            get
            {
    
    
                Console.WriteLine($"【get】 ---> {
      
      list[index].Name} ---> {
      
      list[index].Age}");
                return list[index];
            }

            set
            {
    
    
                Console.WriteLine($"【set】 ---> {
      
      list[index].Name} ---> {
      
      list[index].Age}");
                list[index] = value;
            }
        }
    }
}

简写赋值

internal class Program
{
    
    
    static void Main(string[] args)
    {
    
    
        Person person = new Person
        {
    
    
            name = "Lee",
            age = 20,
        };
        Console.WriteLine(person.name); // Lee
    }
}

class Person
{
    
    
    public string name;
    public int age;
}

委托 delegate

委托特点

  • 是方法类型
  • 事件是属于类的成员,所以是要放在类的内部的。而委托,属于一个定义。其实是和类、接口类似的。通常是放在外部的。因为大多数委托都是要被重用的。
  • 实例化委托对象需要传入方法来实例化
  • 这个方法的返回值类型参数列表需要和委托保持一致
    delegate void FunA();       // 委托的声明
    
    class MainClass
    {
          
          
        public static void Main(string[] args)
        {
          
          
            // 方法类型 - 委托
            // 实例化委托对象需要传入方法来实例化
            // 这个方法的返回值类型和参数列表需要和委托保持一致
            FunA a = new FunA(FunDemo); // => FunA a = FunDemo;
            a(); // FunDemo Show ~
        }
    
        public static void FunDemo() {
          
          
            Console.WriteLine("FunDemo Show ~");
        }
    }
    

委托的使用情景

存在不同角色,每个角色都存在一个F技能,但是每个角色的F技能的表现形式不同

class MainClass
{
    
    
    public static void Main(string[] args)
    {
    
    
        Hero mengya = new Hero();
        mengya.F = Skill.Jibu;
        mengya.F(); // Jibu - 疾步~

        Hero guiguzi = new Hero();
        guiguzi.F = new SkillDelegate(Skill.Zhiliao);
        guiguzi.F(); // Zhiliao - 治疗~

        Hero dianwei = new Hero
        {
    
    
            F = Skill.Chengjie
        };
        dianwei.F(); // Chengjie - 惩戒~
    }
}

delegate void SkillDelegate();          // 声明技能委托

// 英雄类
class Hero {
    
    
    public SkillDelegate F;
}

// 技能类
static class Skill {
    
    
    public static void Jibu()
    {
    
    
        Console.WriteLine("Jibu - 疾步~");
    }

    public static void Chengjie()
    {
    
    
        Console.WriteLine("Chengjie - 惩戒~");
    }

    public static void Zhiliao()
    {
    
    
        Console.WriteLine("Zhiliao - 治疗~");
    }
}

组合委托 相当于按了一个按键施展多个技能

public delegate void SkillDelegate();
    
class MainClass
{
    
    
    public static void Main(string[] args)
    {
    
    
        SkillDelegate ab = MethodA;

        ab += MethodB;
        ab(); // MethodA Show ~  MethodB Show ~

        ab -= MethodA;
        ab(); // MethodB Show ~

        ab -= MethodA;
        ab(); // MethodB Show ~

        ab -= MethodB;
        Console.WriteLine(ab == null); // True

        ab -= MethodB;
        Console.WriteLine(ab == null); // True
    }

    public static void MethodA()
    {
    
    
        Console.WriteLine("MethodA Show ~");
    }

    public static void MethodB()
    {
    
    
        Console.WriteLine("MethodB Show ~");
    }
}

匿名函数

class MainClass
{
    
    
    delegate int NumberChanger(int n);

    public static void Main(string[] args)
    {
    
    

        NumberChanger nc = delegate (int x)
        {
    
    
            Console.WriteLine("Anonymous Method: {0}", x);
            return x;
        };

        nc(123);

    }
}

Lambda =>

class MainClass
{
    
    
    delegate void NumberChanger(int n);

    public static void Main(string[] args)
    {
    
    

        // 写法一
        NumberChanger nc1 = delegate (int x)
        {
    
    
            Console.WriteLine("Anonymous Method: {0}", x);
        };
        nc1(123);

        // 写法二
        NumberChanger nc2 = (int x) =>
        {
    
    
            Console.WriteLine("Anonymous Method: {0}", x);
        };
        nc2(123);

        // 写法三
        NumberChanger nc3 = (int x) => Console.WriteLine("Anonymous Method: {0}", x);
        nc3(123);

        // 写法四
        NumberChanger nc4 = x => Console.WriteLine("Anonymous Method: {0}", x);
        nc4(123);

    }

}

回调

public delegate int Callback(int res);

class MainClass
{
    
    
    public static void Main(string[] args)
    {
    
    
        FunA(1, 2, Result);
    }

    public static int FunA(int x, int y, Callback callback) {
    
    
        int res = x + y;
        return callback(res);
    }

    public static int Result(int res) {
    
    
        Console.WriteLine(res);
        return res;
    }

}

猜你喜欢

转载自blog.csdn.net/weixin_43526371/article/details/128434142