Tang Laoshi C# advanced course exercises (self-written, if there is a better method, welcome to discuss) (2)

Table of contents

Lesson 28 Anonymous Functions

1. Write a function that passes in an integer and returns a function. When the anonymous function is executed later, the integer is passed in and multiplied by the number passed in by the previous function to return the result.

 static Func<int, int> Fun01(int num)
         {
    
    
             return delegate (int a)
             {
    
    
                 return a * num;
             };
         }      

Main function call:

Func<int,int> test = Fun01(4);
Console.WriteLine(test(5)); 

Lesson 30 Lambda Expressions and Closures

1. There is a function that returns a delegate function. There is only one print code in this delegate function. When the returned delegate function is executed, 1~10 can be printed.

static Func<Action> LambdaTest()
        {
    
    
            return () =>
            {
    
    
                Action action =null;
                Console.WriteLine("打印代码");
                for (int i = 1; i < 11; i++)
                {
    
    
                    int index = i;
                    action += () =>
                    {
    
    
                        Console.Write(index);
                    };
                }
                return action;
            };
        }

Main function call:

Func<Action> test = LambdaTest();
test()();

Lesson 32 List sorting

1. Write a monster class, create 10 monsters and add them to the List. Sort the List according to the numbers entered by the user: 1. Attack sorting 2. Defense sorting 3. HP sorting 4. Reverse

Create a monster class:

 class Monister
    {
    
    
        public int att;
        public int def;
        public int hp;
        public Monister(int att,int def,int hp)
        {
    
    
            this.att = att;
            this.def = def;
            this.hp = hp;
        }
        public void ShowInfo()
        {
    
    
            Console.WriteLine("怪物的攻击力为:{0},防御力为:{1},血量为:{2}",att,def,hp);
        }
    }

The main function is called. Here only the attack sorting is demonstrated:

 			List<Monister> monisters = new List<Monister>();
            Random r = new Random();
            for (int i = 0; i < 10; i++)
            {
    
    
                monisters.Add(new Monister(r.Next(1, 100), r.Next(1, 100), r.Next(1, 100)));              
            }
            monisters.Sort((a,b)=> 
            {
    
    
                //此处是按照攻击力排序,其他排序只需更改此处即可,为了节省时间。此处省略
                return a.att > b.att ? -1 : 1;
            });
            foreach (var item in monisters)
            {
    
    
                item.ShowInfo();
            }

2. Write an item class (type, name, quality), create 10 items, add them to the List, and compare using type, quality, and name at the same time. The sorting weight is: type > quality > name length

Item data class:

  class ItemList
    {
    
    
        public int type;
        public string name;
        public int quality;
        public ItemList(int type,string name,int quality)
        {
    
    
            this.type = type;
            this.name = name;
            this.quality = quality;
        }
        public void ShowItemInfo()
        {
    
    
            Console.WriteLine("物品的类型是:{0},品质是:{1},名字是:{2}",type,quality,name);
        }
    }

Main function call:

 			List<ItemList> itemLists = new List<ItemList>();
            Random r = new Random();
            for (int i = 0; i < 10; i++)
            {
    
    
                itemLists.Add(new ItemList(r.Next(1, 5), "" + i + "" + r.Next(100, 100000), r.Next(1, 10)));
            }
            itemLists.Sort((a, b) =>
            {
    
    
                if (a.type != b.type)
                {
    
    
                    return a.type > b.type ? 1 : -1;
                }
                if (a.quality != b.quality)
                {
    
    
                    return a.quality > b.quality ? 1 : -1;
                }
                return a.name.Length > b.name.Length ? 1 : -1;
            });
            foreach (var item in itemLists)
            {
    
    
                item.ShowItemInfo();
            }

operation result:

物品的类型是:1,品质是:3,名字是:136130
物品的类型是:1,品质是:4,名字是:760853
物品的类型是:2,品质是:1,名字是:349943
物品的类型是:2,品质是:1,名字是:261133
物品的类型是:2,品质是:3,名字是:919746
物品的类型是:2,品质是:6,名字是:020356
物品的类型是:2,品质是:7,名字是:419499
物品的类型是:3,品质是:1,名字是:587941
物品的类型是:3,品质是:4,名字是:832324
物品的类型是:4,品质是:7,名字是:672702

3. Please try to use the List sorting method to sort the contents in the Dictionary. Tip: Get all the key-value pair information of the Dictionary and store it in the List.

 			Dictionary<int, string> dic = new Dictionary<int, string>();
            dic.Add(2, "456");
            dic.Add(6, "564");
            dic.Add(1, "456");
            dic.Add(4, "156453");
            dic.Add(3, "15343");
            dic.Add(5, "12233");

            List<KeyValuePair<int, string>> list = new List<KeyValuePair<int, string>>();

            foreach (KeyValuePair<int, string> item in dic)
            {
    
    
                list.Add(item);                
            }

            list.Sort((a, b) =>
            {
    
    
                return a.Key > b.Key ? 1 : -1;
            });

            for (int i = 0; i < list.Count; i++)
            {
    
    
                Console.WriteLine(list[i].Key + "_" + list[i].Value);
            }

Lesson 34 Covariance and contravariance

1. Please describe the role of covariance and contravariance

(Reference here@Aries in April)

            //请描述协变逆变有什么作用

            //是用来修饰泛型替代符的  泛型委托和泛型接口中
            //1.out修饰的泛型类型 只能作为返回值类型 协变
            //  in修饰的泛型类型 只能作为参数类型   逆变

            //2.遵循里氏替换原则 用out和in修饰的泛型委托 如果类型是父子关系 那么可以相互装载
            // 协变: 父类泛型委托容器可以装 子类泛型委托容器 
            // 逆变: 子类泛型委托容器可以装 父类泛型委托容器

2. Explain the role of covariance and contravariance through code

	//通过代码说明协变和逆变的作用
    //协变
    delegate T TestOut<out T>();
    //逆变
    delegate void TestIn<in T>(T v);

    class Father
    {
    
    

    }
    class Son:Father
    {
    
    

    }
    class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            //协变 代码
            TestOut<Son> ts = () =>
            {
    
    
                return new Son();
            };

            TestOut<Father> tf = ts;

            Father f = tf();

            //逆变 代码
            TestIn<Father> tif = (value) =>
            {
    
    

            };

            TestIn<Son> tis = tif;

            tis(new Son());
        }
    }

Lesson 36 Multithreading

1. Implementation of snake movement in Snake

    enum E_MoveDir
    {
    
    
        Up,
        Down,
        Right,
        Left,
    }
    class Icon
    {
    
    
        //当前移动的方向
        public E_MoveDir dir;
        //当前位置
        public int x;
        public int y;
        public Icon(int x, int y, E_MoveDir dir)
        {
    
    
            this.x = x;
            this.y = y;
            this.dir = dir;
        }

        //移动
        public void Move()
        {
    
    
            switch (dir)
            {
    
    
                case E_MoveDir.Up:
                    y -= 1;
                    break;
                case E_MoveDir.Down:
                    y += 1;
                    break;
                case E_MoveDir.Right:
                    x += 2;
                    break;
                case E_MoveDir.Left:
                    x -= 2;
                    break;
            }
        }

        //绘制
        public void Draw()
        {
    
    
            Console.SetCursorPosition(x, y);
            Console.Write("■");
        }
        //擦除
        public void Clear()
        {
    
    
            Console.SetCursorPosition(x, y);
            Console.Write("  ");
        }
        //转向
        public void ChangeDir(E_MoveDir dir)
        {
    
    
            this.dir = dir;
        }
    }

Main function call:

Console.CursorVisible = false;
                icon = new Icon(10, 5, E_MoveDir.Right);
                icon.Draw();

                //开启多线程
                Thread t = new Thread(NewThreadLogic);
                t.IsBackground = true;
                t.Start();

                while (true)
                {
    
    
                    Thread.Sleep(500);
                    icon.Clear();
                    icon.Move();
                    icon.Draw();
                }
            
             void NewThreadLogic()
            {
    
    
                while (true)
                {
    
    
                    switch (Console.ReadKey(true).Key)
                    {
    
    
                        case ConsoleKey.W:
                            icon.ChangeDir(E_MoveDir.Up);
                            break;
                        case ConsoleKey.A:
                            icon.ChangeDir(E_MoveDir.Left);
                            break;
                        case ConsoleKey.S:
                            icon.ChangeDir(E_MoveDir.Down);
                            break;
                        case ConsoleKey.D:
                            icon.ChangeDir(E_MoveDir.Right);
                            break;
                    }
                }

Lesson 38 Preprocessing Commands

1. Please name at least 4 preprocessor directives

            //请说出至少4种预处理器指令
            //#define 定义一个符号 (没有值的变量)
            //#undef 取消定义一个符号

            //#if
            //#elif
            //#else
            //#endif

            //#warning
            //#error

2. Please use the preprocessor instructions to write a function to calculate two numbers. When the Unity5 version is used, the addition is calculated, but when the Unity2017 version is used, the subtraction is calculated. At that time, the subtraction is not returned as 0.


 static int Calc(int a, int b)
        {
    
    
#if Unity5
            return a + b;
#elif Unity2017
            return a * b;
#elif Unity2020
            return a - b;
#else
            return 0;
#endif
        }

Guess you like

Origin blog.csdn.net/u012177821/article/details/130963643