• 用《斗破苍穹》的视角打开C#3 标签与反射(人物创建与斗技使用)


    请添加图片描述

    • 随着剧情的发展,主线人物登场得越来越多,时不时跳出一个大佬,对我张牙舞爪地攻击。
    • 眼花缭乱的斗技让我不厌其烦,一个不小心,我就记不清楚在哪里遇上过什么人,他会什么斗技了。
    • 这时候,我就特别希望有个办法,能把所有登场得人物都自动检测出来,到时候就可以直接调用了。
    • 比方说萧炎和云韵:
    [Hero]
    class 萧炎 {
        [Skill]
        public void 八极崩() { }
        [Skill]
        public void 焰分噬浪尺() { }
        [Skill]
        public void 佛怒火莲() { }
    }
    [Hero]
    class 云韵
    {
        [Skill]
        public void 风之极陨杀() { }
        [Skill]
        public void 风之极落日曜() { }
        [Skill]
        public void 风吹势() { }
        [Skill]
        public void 风灵分形剑() { }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 这里特意用标签标注了哪些是英雄,哪些是技能。
    • 接下来,只要识别这些标签,然后通过反射,就能在最需要的时候,让这些人物登场了。
      请添加图片描述
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace FrameworkDemo
    {
        // 只写Hero也可以,但是规范地写法会加上"Attribute"。
        // 程序在识别时,会自动忽略"Attribute"。
        public class HeroAttribute : Attribute { }
        public class SkillAttribute : Attribute { }
        [Hero]
        class 萧炎 {
            [Skill]
            public void 八极崩() { }
            [Skill]
            public void 焰分噬浪尺() { }
            [Skill]
            public void 佛怒火莲() { }
        }
        [Hero]
        class 云韵
        {
            [Skill]
            public void 风之极陨杀() { }
            [Skill]
            public void 风之极落日曜() { }
            [Skill]
            public void 风吹势() { }
            [Skill]
            public void 风灵分形剑() { }
        }
        class Program
        {
            static private List<Type> heroTypes;                            // 所有英雄类型列表
            static private object selectedHero;                             // 当前选中的英雄对象
            static private ArrayList heroNamesList = new ArrayList();       // 所有英雄名称列表
            static private ArrayList selectedHeroSkill = new ArrayList();  // 当前选中英雄的技能列表
            static private void init() {
                heroTypes = System.Reflection.Assembly.GetExecutingAssembly().GetTypes()    // 正在运行的程序集中的类型
                    .Where(t => t.GetCustomAttributes(typeof(HeroAttribute), false).Any())  // 找到所有带有英雄属性的对象,false表示不搜索继承链
                    .ToList();            
                heroNamesList.AddRange(heroTypes.Select(t => t.Name).ToArray());            // 初始化英雄名称列表,type类型自带Name属性
            }
            static private void showHeros() {
                int count = 1;
                Console.WriteLine("当前已有英雄:");
                foreach (string name in heroNamesList){
                    Console.WriteLine($"{count}:{name}");
                    count++;
                }
                Console.WriteLine("====================");
                Console.WriteLine("请填写选取英雄的序号:");
            }
            static private Type selectHero() {
                int index = Convert.ToInt32(Console.ReadLine());
                if (index > heroTypes.Count || index <= 0) {
                    Console.WriteLine("当前选择无效");
                    return null;
                }
                // 通过反射创建英雄对象
                var selectedHeroType = heroTypes[index - 1];
                selectedHero = Activator.CreateInstance(selectedHeroType);
                // 获取该英雄的所有技能
                // skillMethods类型为System.Reflection.MethodInfo,自带Name属性
                var skillMethods = selectedHeroType.GetMethods()
                    .Where(m => m.GetCustomAttributes(typeof(SkillAttribute), false).Any())
                    .ToList();
                // 初始化技能列表
                selectedHeroSkill.Clear();
                selectedHeroSkill.AddRange(skillMethods.Select(m => m.Name).ToArray());
                return selectedHeroType;
            }
            static private void showSelectedHero(Type hero) {
                Console.WriteLine("====================");
                int index = 1;
                Console.WriteLine("已选择英雄:");
                Console.WriteLine(hero.Name);
                Console.WriteLine("技能为:");
                foreach (string skill in selectedHeroSkill)
                {
                    Console.WriteLine($"{index}:{skill}");
                    index++;
                }
                Console.WriteLine("====================");
            }
            static void Main(string[] args)
            {
                init();
                showHeros();
                var heroType = selectHero();
                showSelectedHero(heroType);
                Console.ReadLine();
            }
        }
    }
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 于是乎,这个世界就变成了这样:
      请添加图片描述
      其实,还不错啦~~~
      请添加图片描述
  • 相关阅读:
    matlab中的神经网络怎么用,matlab怎么搭建神经网络
    基于SVM+TensorFlow+Django的酒店评论打分智能推荐系统——机器学习算法应用(含python工程源码)+数据集+模型(二)
    基于Lucas-Kanade算法的三维光流提取matlab仿真
    【JavaWeb】简易表白墙的设计
    6 个最佳免费 Android 数据恢复软件
    快速入门SpringMVC,详解原理
    选择类排序法
    艾美捷曲妥珠单抗Trastuzumab化学性质和特异性说明
    android 键盘遮挡输入框问题回忆
    springboot运维篇--springboot项目打包
  • 原文地址:https://blog.csdn.net/Nire_Yeyu/article/details/133652516