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

  • 随着剧情的发展,主线人物登场得越来越多,时不时跳出一个大佬,对我张牙舞爪地攻击。
  • 眼花缭乱的斗技让我不厌其烦,一个不小心,我就记不清楚在哪里遇上过什么人,他会什么斗技了。
  • 这时候,我就特别希望有个办法,能把所有登场得人物都自动检测出来,到时候就可以直接调用了。
  • 比方说萧炎和云韵:
csharp 复制代码
[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 风灵分形剑() { }
}
  • 这里特意用标签标注了哪些是英雄,哪些是技能。
  • 接下来,只要识别这些标签,然后通过反射,就能在最需要的时候,让这些人物登场了。
csharp 复制代码
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();
        }
    }
}
  • 于是乎,这个世界就变成了这样:

    其实,还不错啦~~~
相关推荐
Clockwiseee6 小时前
php伪协议
windows·安全·web安全·网络安全
向宇it7 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
数据的世界017 小时前
.NET开发人员学习书籍推荐
学习·.net
唐宋元明清21888 小时前
.NET 阻止系统睡眠/息屏
windows·电源
向宇it8 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
paixiaoxin9 小时前
CV-OCR经典论文解读|An Empirical Study of Scaling Law for OCR/OCR 缩放定律的实证研究
人工智能·深度学习·机器学习·生成对抗网络·计算机视觉·ocr·.net
yylの博客10 小时前
Windows通过git-bash安装zsh
windows·git·bash·zsh
进击的code10 小时前
windows 下使用WLS2 编译aosp Android14并刷机到pixle 5a
windows
坐井观老天13 小时前
在C#中使用资源保存图像和文本和其他数据并在运行时加载
开发语言·c#
染指111013 小时前
50.第二阶段x86游戏实战2-lua获取本地寻路,跨地图寻路和获取当前地图id
c++·windows·lua·游戏安全·反游戏外挂·游戏逆向·luastudio