• C#中反射的用法和使用场景介绍
  • 发布于 2个月前
  • 287 热度
    0 评论
反射是一种“程序即数据”范例,它能让程序的一部分根据程序集、类型和成员动态查询和/或调用另一部分。它对于后期绑定编程模型和工具特别有用。 
以下代码使用反射来查找和调用 type。
// 堆代码 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 类型系统。 


反射还启用了一种单独的模式,其中生成的 IL 字节代码可以在运行时进行 JIT 编译,有时用于以专用算法替换通用算法。有了对象模型和其他细节,它通常会被用于序列化器或对象关系映射器中。
用户评论