如何在不使用反射的情况下随机获取Letter类的子类实例?
解决方案
核心思路是让每个子类主动注册自己的实例创建逻辑,基类维护一个可创建实例的委托集合,随机选取执行即可,完全满足「不用反射、新增子类无需修改Get方法」的要求。
实现步骤
1. 修改基类Letter,添加注册集合与随机方法
using System; using System.Collections.Generic; public class Letter { // 存储所有子类的实例创建委托 private static readonly List<Func<Letter>> _letterFactories = new List<Func<Letter>>(); // 全局随机实例,避免重复创建导致随机分布不均 private static readonly Random _random = new Random(); // 供子类注册的方法 protected static void RegisterFactory(Func<Letter> factory) { if (factory == null) throw new ArgumentNullException(nameof(factory)); _letterFactories.Add(factory); } public static Letter GetRandomLetter() { if (_letterFactories.Count == 0) throw new InvalidOperationException("没有注册任何Letter子类"); var selectedFactory = _letterFactories[_random.Next(_letterFactories.Count)]; return selectedFactory(); } }
2. 子类实现自动注册
每个子类只需要在静态构造函数里调用基类的注册方法,传入自己的实例创建逻辑即可:
public class A : Letter { static A() { RegisterFactory(() => new A()); } // 子类自身的业务逻辑... } public class B : Letter { static B() { RegisterFactory(() => new B()); } // 子类自身的业务逻辑... }
方案优势
- 无反射开销:所有实例创建都是显式委托调用,性能优异,适配数千个子类的场景。
- 新增子类零改动:后续添加任何Letter子类,仅需在自身静态构造函数中写一行注册代码,完全不用修改
GetRandomLetter方法。 - 自动触发注册:.NET会在第一次访问子类(创建实例、访问静态成员)时自动执行静态构造函数,确保注册逻辑被触发。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

