Tang Laoshi C#-Kursübungen für Fortgeschrittene (selbst geschrieben, wenn es einen besseren Weg gibt, gerne besprechen) (1)

Übungen zum C#-Fortgeschrittenenkurs von Tang Laoshi (selbst geschrieben, wenn es einen besseren Weg gibt, kann er gerne besprochen werden)

Inhaltsverzeichnis

Lektion 4 Stapelstapel:

1. Beschreiben Sie kurz die Speicherregeln des Stapels: Zuerst rein, zuletzt raus

2. Schreiben Sie eine Methode, um die Binärzahl einer beliebigen Zahl zu berechnen, speichern Sie sie in einer Stapelstruktur und drucken Sie sie dann aus

 private static void ToBinarySystem(int num)
        {
    
    
            Stack stack = new Stack();
            for (;num >= 1;)
            {
    
    
                stack.Push(num % 2);
                num = num / 2;
            }
            foreach (var item in stack)
            {
    
    
                Console.Write(item);
            }         
        }

Lektion 6 Warteschlange Warteschlange

1. Beschreiben Sie kurz die Speicherregeln der Warteschlange: First In, First Out

2. Verwenden Sie die Warteschlange zum Speichern von Nachrichten, zum gleichzeitigen Speichern von 10 Nachrichten und zum Drucken einer Nachricht von Zeit zu Zeit. Beim Drucken von Nachrichten sollte die Konsole ein klares Pausengefühl haben (das Pausengefühl wurde noch nicht erkannt).

static void PrintQueue()
        {
    
    
            Queue queue = new Queue();
            for (int i = 0; i < 10; i++)
            {
    
    
                queue.Enqueue(i);
            }

            foreach (var item in queue)
            {
    
    
                Console.WriteLine(item);
            }
        }

Das Folgende ist die Wirkung von Ghostwriting mit künstlicher Intelligenz als Referenz:

using System;
using System.Collections.Generic;
using System.Threading;

public class MessageQueue
{
    
    
    private Queue<string> queue;
    private int maxCount;
    private int printInterval;

    public MessageQueue(int maxCount, int printInterval)
    {
    
    
        this.queue = new Queue<string>();
        this.maxCount = maxCount;
        this.printInterval = printInterval;
    }

    public void Enqueue(string message)
    {
    
    
        lock (queue)
        {
    
    
            queue.Enqueue(message);
            if (queue.Count == maxCount)
            {
    
    
                PrintMessages();
            }
        }
    }

    private void PrintMessages()
    {
    
    
        Console.WriteLine("Printing messages...");
        while (queue.Count > 0)
        {
    
    
            Thread.Sleep(printInterval);
            Console.WriteLine(queue.Dequeue());
        }
    }
}

public class Program
{
    
    
    public static void Main()
    {
    
    
        MessageQueue messageQueue = new MessageQueue(10, 1000);
        for (int i = 0; i < 10; i++)
        {
    
    
            messageQueue.Enqueue($"Message {
      
      i + 1}");
        }
    }
}

Lektion 8 Hashtable-Tabelle

1. Bitte beschreiben Sie die Speicherregeln von Hashtable: Speicherung über Schlüssel-Wert-Paare

2. Erstellen Sie einen Monster-Manager, der Methoden zum Erstellen und Entfernen von Monstern bereitstellt. Jedes Monster hat seine eigene eindeutige ID

Monster-Manager-Klasse:

    /// <summary>
    /// 怪物管理器,提供创建怪物,移除怪物的方法。每个怪物都有自己的唯一ID
    /// </summary>
    class MonsterManager
    {
    
    
        //创建怪物的哈希表
        Hashtable monsterHashtable = new Hashtable();
        
        /// <summary>
        /// 创建怪物
        /// </summary>
        /// <param name="id">怪物的ID</param>
        /// <param name="name">怪物的名字</param>
        public void CreateMonster(int id,string name)
        {
    
    
            //判断现有的怪物哈希表里面存不存在要加入的怪物
            if (!monsterHashtable.Contains(id))
            {
    
    
                //不存在,在哈希表里面加入怪物
                monsterHashtable.Add(id, name);
            }
            else
            {
    
    
                //存在,给用户一个输出提示
                Console.WriteLine("已存在此怪物ID");
            }
        }

        /// <summary>
        /// 通过ID移除怪物
        /// </summary>
        /// <param name="id">怪物ID</param>
        public void RemoveMonster(int id)
        {
    
    
            //判断存不存在要删除的怪物
            if (monsterHashtable.Contains(id))
            {
    
    
                //存在,删除怪物
                monsterHashtable.Remove(id);
            }
            else
            {
    
    
                Console.WriteLine("不存在此怪物");
            }
        }

        /// <summary>
        /// 便利当前哈希表中的所有怪物
        /// </summary>
        public void ShowMonster()
        {
    
    
            foreach (var item in monsterHashtable.Keys)
            {
    
    
                Console.WriteLine("怪物ID:"+item+"\t 怪物名字:"+monsterHashtable[item]);
            }
        }
    }

Hauptfunktionsaufruf:

static void Main(string[] args)
        {
    
    
            MonsterManager monsterMgr = new MonsterManager();
            monsterMgr.CreateMonster(1, "1号怪物");
            monsterMgr.CreateMonster(2, "2号怪物");
            monsterMgr.CreateMonster(3, "3号怪物");
            monsterMgr.ShowMonster();
            Console.WriteLine("********进行删除操作**********");
            monsterMgr.RemoveMonster(2);
            monsterMgr.ShowMonster();
            Console.ReadKey();
        }

Operationsergebnis

怪物ID:3        怪物名字:3号怪物
怪物ID:2        怪物名字:2号怪物
怪物ID:1        怪物名字:1号怪物
********进行删除操作**********
怪物ID:3        怪物名字:3号怪物
怪物ID:1        怪物名字:1号怪物

Lektion 10 Allgemeine Wissenspunkte

1. Definieren Sie eine generische Methode zur Bestimmung des Typs

Definieren Sie eine generische Methode, die den Typ des Typs bestimmt und den Namen des Typs sowie die Anzahl der von ihm belegten Bytes zurückgibt. Wenn es ein int ist, wird „integer, 4 Bytes“ zurückgegeben. Es werden nur die folgenden Typen berücksichtigt: int: integer
char
:
Zeichen
float: Gleitkommazahl mit einfacher Genauigkeit
string: String
Wenn es sich um andere Typen handelt, geben Sie „andere Typen“ zurück
(Typbeurteilung kann durch typeof(type) == typeof(type) erfolgen)

private static string JudgmentType<T>()
        {
    
    
           
            if (typeof(T) == typeof(int))
            {
    
    
                return "整形" + "\t" + sizeof(int)+"字节";
            }
            else if(typeof(T) == typeof(char))
            {
    
    
                return "字符" + "\t" + sizeof(char) + "字节";
            }
            else if (typeof(T) == typeof(float))
            {
    
    
                return "单精度浮点数" + "\t" + sizeof(float) + "字节";
            }
            else if (typeof(T) == typeof(string))
            {
    
    
                return "字符串" + "\t" + "没有预定字节";
            }
            else
            {
    
    
                return "其他类型";
            }           
        }

Lektion 12 Allgemeine Einschränkungen

1. Verwenden Sie Generika, um eine Singleton-Muster-Basisklasse zu implementieren

Der hier bereitgestellte Code ist die in Unity verwendete Singleton-Muster-Basisklasse

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 定义一个基类,用于实现单例模式
public abstract class Singleton<T> : MonoBehaviour where T : Singleton<T>
{
    
    
    // 加锁的对象,用于线程安全
    private static readonly object _lock = new object();
    // 静态变量,用于存储单例实例
    private static T _instance = null;

    // 静态属性,用于获取单例实例
    public static T Instance
    {
    
    
        get {
    
    
            // 加锁,保证在多线程环境中只有一个实例被创建
            lock (_lock) {
    
    
                if (_instance == null)
                    _instance = FindObjectOfType<T>(); // 查找场景中是否已经存在该类型的对象
                return _instance;
            }
        }
    }

    // 在 Awake() 中进行初始化,并处理多实例的情况
    protected virtual void Awake()
    {
    
    
        // 加锁,保证在多线程环境中只有一个实例被创建
        lock (_lock) {
    
    
            // 第一次创建实例时,将自己设置为单例实例,不销毁该对象
            if (_instance == null) {
    
    
                _instance = (T)this;
                DontDestroyOnLoad(gameObject); // 如果需要跨场景使用单例,使用 DontDestroyOnLoad 保持对象不被销毁
            } 
            // 如果不同的实例被创建,销毁新的实例,保证单例的唯一性
            else if (_instance != this) {
    
    
                Destroy(gameObject);
            }
        }
    }

    // 如果该实例被销毁,将实例设置为空
    protected virtual void OnDestroy()
    {
    
    
        if (_instance == this) {
    
    
            _instance = null;
        }
    }
}

2. Verwenden Sie generische Wissenspunkte, um ArrayList zu imitieren und eine Klasse mit unsicherem Array-Typ zu implementieren, um die Methoden zum Hinzufügen, Löschen, Überprüfen und Ändern zu implementieren.

class ArrayList<T>
    {
    
    
        private T[] items;
        public ArrayList()
        {
    
    
            items = new T[0];
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="value"></param>
        public void Add(T value)
        {
    
    
            T[] newItems = new T[items.Length + 1];
            for (int i = 0; i < items.Length; i++)
            {
    
    
                newItems[i] = items[i];
            }
            newItems[newItems.Length - 1] = value;
            items = newItems;

        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="index"></param>
        public void RemoveAt(int index)
        {
    
    
            if (index < 0 || index >= items.Length)
            {
    
    
                throw new IndexOutOfRangeException();
            }

            T[] newItems = new T[items.Length - 1];
            for (int i = 0, j = 0; i < items.Length; i++)
            {
    
    
                if (i != index)
                {
    
    
                    newItems[j] = items[i];
                    j++;
                }
            }
            items = newItems;
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T Get(int index)
        {
    
    
            if (index < 0 || index >= items.Length)
            {
    
    
                throw new IndexOutOfRangeException();
            }

            return items[index];
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public void Set(int index, T value)
        {
    
    
            if (index < 0 || index >= items.Length)
            {
    
    
                throw new IndexOutOfRangeException();
            }

            items[index] = value;
        }

        public int Count()
        {
    
    
            return items.Length;
        }
    }

Hauptfunktionsaufruf:

 static void Main(string[] args)
        {
    
    
            ArrayList<int> intArray = new ArrayList<int>();
            intArray.Add(1);
            intArray.Add(2);
            intArray.Add(3);
            intArray.RemoveAt(1);
            intArray.Set(1, 4);
            Console.WriteLine(intArray.Get(0)); // 输出 1
            Console.WriteLine(intArray.Get(1)); // 输出 4
            Console.WriteLine(intArray.Count()); // 输出 2

            ArrayList<string> stringArray = new ArrayList<string>();
            stringArray.Add("apple");
            stringArray.Add("banana");
            stringArray.Add("orange");
            stringArray.RemoveAt(2);
            stringArray.Set(0, "pear");
            Console.WriteLine(stringArray.Get(0)); // 输出 pear
            Console.WriteLine(stringArray.Get(1)); // 输出 banana
            Console.WriteLine(stringArray.Count()); // 输出 2

            Console.ReadKey();
        }

Lektion 14 Wissenspunkte auflisten

1. Bitte beschreiben Sie den Unterschied zwischen List und ArrayList

1. List unterstützt Generika, ArrayList unterstützt keine Generika.
2. List verfügt nicht über Boxing- und Unboxing-Vorgänge, während ArrayList über Boxing- und Unboxing-Vorgänge verfügt.

2. Erstellen Sie eine Ganzzahlliste, fügen Sie 10 ~ 1 hinzu, löschen Sie das fünfte Element in der Liste, durchlaufen Sie die verbleibenden Elemente und drucken Sie sie aus

			List<int> list = new List<int>();
            for (int i = 10; i > 0; i--)
            {
    
    
                list.Add(i);
            }
            list.RemoveAt(4);
            foreach (var item in list)
            {
    
    
                Console.Write(item+"\t");
            }

3. Eine Monster-Basisklasse, von der die Klassen Boss und Gablin erben. Im Konstruktor der Monsterklasse kann das Speichern in einer Monsterliste und das Durchlaufen der Liste dazu führen, dass Boss- und Gablin-Objekte unterschiedliche Angriffe ausführen.

 class Monster
     {
    
    
        public static List<Monster> monsters = new List<Monster>();
        public Monster()
        {
    
    
            monsters.Add(this);
        }
        public virtual void Attack()
        {
    
    
            Console.WriteLine("MonsterAtt");
        }
     }

    class Boss : Monster
    {
    
    
        public override void Attack()
        {
    
    
            Console.WriteLine("BossAtt");
        }
    }
    class Goblin : Monster
    {
    
    
        public override void Attack()
        {
    
    
            Console.WriteLine("GoblinAtt");
        }
    }

Hauptfunktionsaufruf:

 Boss boss = new Boss();
            Goblin goblin = new Goblin();
            foreach (var item in Monster.monsters)
            {
    
    
                item.Attack();
            }

Lektion 16 Wörterbuch-Wissenspunkte

1. Verwenden Sie ein Wörterbuch, um den Großbuchstabentext zu speichern, der den Zahlen von 0 bis 9 entspricht. Fordern Sie den Benutzer auf, eine Zahl mit höchstens drei Ziffern einzugeben. Stellen Sie eine Methode zur Rückgabe der Großbuchstabenzahl bereit. Beispiel: 306, drei Nullen werden zurückgegeben.

			Console.WriteLine("请输入一个不超过3位的数");
            Console.WriteLine(GetInfo(int.Parse(Console.ReadLine())));
            
            string GetInfo(int num)
            {
    
    
                Dictionary<int, string> dic = new Dictionary<int, string>();
                dic.Add(0, "零");
                dic.Add(1, "壹");
                dic.Add(2, "贰");
                dic.Add(3, "叁");
                dic.Add(4, "肆");
                dic.Add(5, "伍");
                dic.Add(6, "陆");
                dic.Add(7, "柒");
                dic.Add(8, "捌");
                dic.Add(9, "玖");

                string str = "";
                //得百位
                int b = num / 100;
                if (b != 0)
                {
    
    
                    str += dic[b];
                }
                //得十位数
                int s = num % 100 / 10;
                if (s != 0 || str != "")
                {
    
    
                    str += dic[s];
                }
                //得个位
                int g = num % 10;
                str += dic[g];

                return str;
            }

2. Berechnen Sie, wie oft jeder Buchstabe „Willkommen in der Unity World!“ vorkommt, verwenden Sie ein Wörterbuch, um ihn zu speichern, und durchlaufen Sie schließlich das gesamte Wörterbuch, ohne Berücksichtigung der Groß- und Kleinschreibung

 string str = "Welcome to Unity World!";
            Dictionary<char, int> strDic = new Dictionary<char, int>();
            for (int i = 0; i < str.Length; i++)
            {
    
    
                if (strDic.ContainsKey(str[i]))
                {
    
    
                    strDic[str[i]]+=1;
                }
                else
                {
    
    
                    strDic.Add(str[i], 1);
                }
            }

            foreach (var item in strDic.Keys)
            {
    
    
                Console.WriteLine("字母{0}出现了{1}次",item,strDic[item]);
            }

Lektion 18 Wissenspunkte zur sequentiellen Speicherung und Kettenspeicherung

1. Bitte sagen Sie mir, welche Datenstrukturen häufig verwendet werden

Array, Stapel, Warteschlange, verknüpfte Liste, Baum, Diagramm, Heap, Hash-Tabelle

2. Bitte beschreiben Sie den Unterschied zwischen sequentiellem Speicher und Kettenspeicher

Sequentielle Speicherung: Verwenden Sie eine Reihe kontinuierlicher Adressspeichereinheiten im Speicher, um lineare Tabellen zu speichern (serielle Adressspeicherung).
Kettenspeicher: Verwenden Sie eine Gruppe beliebiger Speichereinheiten im Speicher, um lineare Tabellen zu speichern (beliebige Adressspeicherung).

3. Versuchen Sie bitte, selbst eine doppelt verknüpfte Liste zu implementieren und stellen Sie die folgenden Methoden und Attribute bereit: Anzahl der Daten, Kopfknoten, Endknoten, Hinzufügen von Daten am Ende der verknüpften Liste und Löschen des Knotens an der angegebenen Position.

Code für die verknüpfte Liste:

    /// <summary>
    /// 链表节点
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    class LinkedNode<T>
    {
    
    
        public T value;
        public LinkedNode<T> frontNode;//上一个链表节点
        public LinkedNode<T> nextNode;//下一个链表节点

        public LinkedNode(T value)
        {
    
    
            this.value = value;
        }      
    }   
    /// <summary>
    /// 链表
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    class LinkedList<T>
    {
    
    
        private int count = 0;
        private LinkedNode<T> head;
        private LinkedNode<T> last;
        public LinkedNode<T> Head {
    
     get {
    
     return head; } }
        public LinkedNode<T> Last {
    
     get {
    
     return last; } }
        public int Count {
    
     get {
    
     return count; } }

        public void Add(T value)
        {
    
    
            LinkedNode<T> node = new LinkedNode<T>(value);
            if (head == null)
            {
    
    
                head = node;
                last = node;
            }
            else
            {
    
    
                //添加一个数据,添加到尾部
                //让尾部的下一个节点等于要加入的节点
                last.nextNode = node;
                //要加入的节点的上一步节点等于尾部节点
                node.frontNode = last;
                //尾部节点替换为当前加入的节点
                last = node;
            }
            ++count;//添加了一个节点
        }

        public void RemoveAt(int index)
        {
    
    
            //不能越界
            if (index >= count || index < 0)
            {
    
    
                Console.WriteLine("只有{0}个节点,请输入合法位置", count);
                return;
            }
            int tempCount = 0;
            LinkedNode<T> tempNode = head;
            while (true)
            {
    
    
                //如果是要移除的节点,那么直接移除
                if (tempCount == index)
                {
    
                      
                    //如果是头节点,那么头节点就等于下一个节点
                    if (index==0)
                    {
    
    
                        head = head.nextNode;
                    }else if (index == count - 1)
                    {
    
    
                        //如果是尾节点,那么让尾节点的上一节点为尾节点
                        last = last.frontNode;
                    }

                    //如果是中部节点
                    if (tempNode.frontNode != null)
                    {
    
    
                        //如果上一个节点不为空。则让上一个节点的下一个节点等于自身的下一个节点
                        tempNode.frontNode.nextNode = tempNode.nextNode;
                    }
                    if (tempNode.nextNode != null)
                    {
    
    
                        //如果下一个节点不为空,则让下一个节点的上一个节点等于自身的上一个节点
                        tempNode.nextNode.frontNode = tempNode.frontNode;
                    }
                    //移除了一个元素,少一截
                    --count;
                    break;
                }

                //每次循环过后临时节点等于下一节点
                tempNode = tempNode.nextNode;
                ++tempCount;
            }

        }
    }

Hauptfunktionsaufruf:

            LinkedList<int> link = new LinkedList<int>();
            link.Add(1);
            link.Add(2);
            link.Add(3);
            link.Add(4);
            LinkedNode<int> node=link.Head;
            while (node != null)
            {
    
    
                Console.WriteLine(node.value);
                node = node.nextNode;
            }
            Console.WriteLine("********************");
            link.RemoveAt(2);
            node = link.Head;
            while (node != null)
            {
    
    
                Console.WriteLine(node.value);
                node = node.nextNode;
            }

Operationsergebnis:

1
2
3
4
********************
1
2
4

Lektion 20 LinkedList-Wissenspunkte

1. Verwenden Sie Linkedlist, fügen Sie 10 zufällige Ganzzahlvariablen hinzu, durchlaufen Sie einmal die Vorwärtsrichtung, um die Informationen auszudrucken, und durchlaufen Sie einmal die Rückwärtsrichtung, um die Informationen auszudrucken.

            LinkedList<int> linkedList = new LinkedList<int>();
            Random r = new Random();
            for (int i = 0; i < 10; i++)
            {
    
    
                linkedList.AddLast(r.Next(1, 101));
            }

            LinkedListNode<int> nowNode = linkedList.First;
            while (nowNode != null)
            {
    
    
                Console.WriteLine(nowNode.Value);
                nowNode = nowNode.Next;
            }

            Console.WriteLine("********************");
            nowNode = linkedList.Last;
            while (nowNode != null)
            {
    
    
                Console.WriteLine(nowNode.Value);
                nowNode = nowNode.Previous;
            }

Lektion 24 Delegierte Wissenspunkte

1. Es gibt eine dreiköpfige Familie. Die Mutter kocht, und der Vater, die Mutter und die Kinder müssen alle essen. Verwenden Sie die Delegation, um den Prozess des Kochens -> Beginn der Mahlzeit -> Essen zu simulieren.

    //一家三口,妈妈做饭,爸爸妈妈和孩子都要吃饭
    //用委托模拟做饭——>开饭——>吃饭的过程
    abstract class Person
    {
    
    
        public abstract void Eat();
    }

    class Mother : Person
    {
    
    
        public Action beginEat;

        public override void Eat()
        {
    
    
            Console.WriteLine("妈妈吃饭");
        }

        public void DoFood()
        {
    
    
            Console.WriteLine("妈妈做饭");

            Console.WriteLine("妈妈做饭做好了");

            //执行委托函数
            if(beginEat != null)
            {
    
    
                beginEat();
            }
        }
    }

    class Father:Person
    {
    
    
        public override void Eat()
        {
    
    
            Console.WriteLine("爸爸吃饭");
        }
    }

    class Son:Person
    {
    
    
        public override void Eat()
        {
    
    
            Console.WriteLine("孩子吃饭");
        }
    }
    class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            Console.WriteLine("委托练习题");

            Mother m = new Mother();
            Father f = new Father();
            Son s = new Son();
            //告诉妈妈 一会做好了 我要吃
            m.beginEat += f.Eat;
            m.beginEat += s.Eat;
            m.beginEat += m.Eat;
            //做饭
            m.DoFood();
            }
        }

2. Nachdem das Monster gestorben ist, muss der Spieler 10 Yuan hinzufügen, die Schnittstelle muss die Daten aktualisieren und der Erfolg muss die Anzahl der getöteten Monster akkumulieren. Bitte verwenden Sie die Provision, um diese Funktionen zu simulieren und zu realisieren, und verwenden Sie nur die Kernlogik, um diesen Prozess auszudrücken, ohne zu kompliziert zu schreiben

    //怪物死亡后,玩家要加10块钱,界面要更新数据
    //成就要累加怪物击杀数,请用委托来模拟实现这些功能
    //只用写核心逻辑表现这个过程,不用写的太复杂

    class Monster
    {
    
    
        //当怪物死亡时 把自己作为参数传出去 
        public Action<Monster> deadDoSomthing;
        //怪物成员变量 特征 价值多少钱
        public int money = 10;

        public void Dead()
        {
    
    
            Console.WriteLine("怪物死亡");
            if(deadDoSomthing != null)
            {
    
    
                deadDoSomthing(this);
            }
            //一般情况下 委托关联的函数 有加 就有减(或者直接清空)
            deadDoSomthing = null;
        }
    }

    class Player
    {
    
    
        private int myMoney = 0;

        public void MonsterDeadDoSomthing(Monster m)
        {
    
    
            myMoney += m.money;
            Console.WriteLine("现在有{0}元钱", myMoney);
        }
    }

    class Panel
    {
    
    
        private int nowShowMoney = 0;

        public void MonsterDeadDo(Monster m)
        {
    
    
            nowShowMoney += m.money;
            Console.WriteLine("当前面板显示{0}元钱", nowShowMoney);
        }
    }

    class CJ
    {
    
    
        private int nowKillMonsterNum = 0;

        public void MonsterDeadDo(Monster m)
        {
    
    
            nowKillMonsterNum += 1;
            Console.WriteLine("当前击杀了{0}怪物", nowKillMonsterNum);
        }
    }
        class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            Monster monster = new Monster();
            Player p = new Player();
            Panel panel = new Panel();
            CJ cj = new CJ();

            monster.deadDoSomthing += p.MonsterDeadDoSomthing;
            monster.deadDoSomthing += panel.MonsterDeadDo;
            monster.deadDoSomthing += cj.MonsterDeadDo;

            monster.Dead();
            monster.Dead();

            Monster monster2 = new Monster();
            monster2.deadDoSomthing += p.MonsterDeadDoSomthing;
            monster2.deadDoSomthing += panel.MonsterDeadDo;
            monster2.deadDoSomthing += cj.MonsterDeadDo;
            monster2.Dead();
        }
    }

Lektion 26 Event-Wissenspunkte

1. Es gibt einen Warmwasserbereiter, der eine Heizung, einen Alarm und ein Display umfasst. Wir schalten den Warmwasserbereiter ein. Wenn die Wassertemperatur 95 Grad überschreitet, 1. ertönt der Alarm und teilt Ihnen mit, wessen Temperatur vorliegt es ist. 2. Das Display ändert auch die Wassertemperaturaufforderung und zeigt damit an, dass das Wasser kocht

Nicht gut geschrieben, nur als Referenz

    /// <summary>
    /// 热水器
    /// </summary>
    class Calorifier
    {
    
    
        public static event Action<int> MyEvent;

        public void BeginPower()
        {
    
    
            Heater heater = new Heater();
            heater.BeginHeater();
        }
        public static void CallEvent(int temp)
        {
    
    
            MyEvent?.Invoke(temp);
        }
    }
    /// <summary>
    /// 加热器
    /// </summary>
    class Heater
    {
    
    
        int temp = 80;
        public void BeginHeater()
        {
    
    
            while (true)
            {
    
    
                if (temp < 95)
                {
    
    
                    temp++;
                    Console.WriteLine("加热!!!\t"+temp);
                }
                if (temp >= 95)
                {
    
    
                    //报警器会开始发出语音,告诉你谁的温度
                    Alarm alarm = new Alarm();
                    //显示器也会改变水温提示,提示水已经烧开了
                    Monitor monitor = new Monitor();
                    Calorifier.CallEvent(temp);
                    break;
                }
            }
        }
        
    }
    /// <summary>
    /// 报警器
    /// </summary>
    class Alarm
    {
    
    
        public Alarm()
        {
    
    
            Calorifier.MyEvent += AlarmBegin;
        }

        private void AlarmBegin(int temp)
        {
    
    
            Console.WriteLine("发出报警声!!!"+temp);
        }
    }
    /// <summary>
    /// 显示器
    /// </summary>
    class Monitor
    {
    
    
        public Monitor()
        {
    
    
            Calorifier.MyEvent += MonitorBegin;
        }

        private void MonitorBegin(int temp)
        {
    
    
            Console.WriteLine("当前温度:" + temp+"水开了,已停止加热");
        }
    }

Hauptfunktionsaufruf:

            Calorifier calor = new Calorifier();
            calor.BeginPower();

Operationsergebnis:

加热!!!      81
加热!!!      82
加热!!!      83
加热!!!      84
加热!!!      85
加热!!!      86
加热!!!      87
加热!!!      88
加热!!!      89
加热!!!      90
加热!!!      91
加热!!!      92
加热!!!      93
加热!!!      94
加热!!!      95
发出报警声!!!95
当前温度:95水开了,已停止加热

Ich denke du magst

Origin blog.csdn.net/u012177821/article/details/130943016
Empfohlen
Rangfolge