// 堆代码 duidaima.com foreach (Type type in typeof(Program).Assembly.DefinedTypes) { if (type.IsAssignableTo(typeof(IStory)) && !type.IsInterface) { IStory? story = (IStory?)Activator.CreateInstance(type); if (story is not null) { var text = story.TellMeAStory(); Console.WriteLine(text); } } } interface IStory { string TellMeAStory(); } class BedTimeStore : IStory { public string TellMeAStory() => "Once upon a time, there was an orphan learning magic ..."; } class HorrorStory : IStory { public string TellMeAStory() => "On a dark and stormy night, I heard a strange voice in the cellar ..."; }
此代码动态枚举实现特定接口的所有程序集类型,实例化每个类型的实例,并通过该接口调用对象的方法。代码本来可以静态编写的,因为它只查询它所引用的程序集中的类型,但要这样做,需要将所有实例的集合(也许是作为一个 List<IStory>)交给它来处理。如果此算法从加载项目录加载任意程序集,则更有可能使用这种后期绑定方法。
有这样一种情况:您无法提前获取程序集和类型,反射通常就被用在这样的场景中。
反射可能是 .NET 中提供的最动态的系统。它旨在使开发人员能够创建自己的二进制代码加载器和方法分派器,其语义可以与静态代码策略(由运行时定义)相匹配或有所区别。反射公开了一个丰富的对象模型,它可以直接用于简单的用例,但随着场景变得更加复杂,您就需要更深入地了解 .NET 类型系统。