【问题标题】:Why is the use of reflection in .NET recommended?为什么推荐在 .NET 中使用反射?
【发布时间】:2009-09-22 05:30:41
【问题描述】:

使用它绝对是一个好习惯吗?

项目中有哪些可能的情况需要反思?

【问题讨论】:

标签: c# .net reflection


【解决方案1】:

Reflection 的主要价值在于它可以用于检查程序集、类型和成员。它是用于确定未知程序集或对象的内容的非常强大的工具,可用于多种情况。

反射的反对者会说它很慢,与静态代码执行相比确实如此——但是反射在整个 .NET 框架中都被使用,并且只要它没有被滥用,它可以成为工具包中非常强大的工具.

一些有用的应用:

  • 确定程序集的依赖关系

  • 符合接口的位置类型,派生自基类/抽象类,并通过属性搜索成员

  • (Smelly) 测试 - 如果你依赖于一个不可测试的类(即它不允许你轻易地构建一个假的),你可以使用反射在类中注入假值——它不漂亮,不推荐,但它可以是绑定中的一个方便的工具。

  • 调试 - 导出已加载程序集的列表、它们的引用、当前方法等...

【讨论】:

  • 几乎所有测试框架都使用反射来开始、查找和执行测试...
【解决方案2】:

反射有很多用途:

  1. 遍历对象中的属性。
  2. 调用在运行时定义的方法。
  3. 许多其他人在同一脉络。

然而,我最喜欢的反射用途之一是查找已用属性标记的属性。

例如,我编写了一些属性来标记我的类中的哪些属性应该使用 Lucene 进行索引。在运行时,我可以查看任何类,并通过查询类的“标记”属性来确定需要索引哪些字段。

【讨论】:

    【解决方案3】:

    反射只是在运行时调查对象的一种方式。如果您不需要这样做,则不应使用它。

    【讨论】:

    • 确实如此。反射是一种非常强大的资源,但它需要履行职责,因此除非确实必要,否则不应使用它。
    • @Konamiman:我不能再同意了,就这么简单。此外,反射经常被滥用,在这种情况下,更简单和更好规划的架构可以轻松解决相同的问题,并获得更好的性能。
    【解决方案4】:

    反射 允许应用程序收集有关自身的信息并对其自身进行操作。它可用于查找程序集中的所有类型和/或动态调用程序集中的方法。

    System.Reflection: 命名空间包含提供加载类型、方法和字段的托管视图的类和接口,能够动态创建和调用类型;这个过程在 .NET 框架中称为反射。

    System.Type: 类是 .NET 反射功能的主要类,是访问元数据的主要方式。 System.Type 类是一个抽象类,代表通用类型系统 (CLS) 中的一种类型。

    它表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义以及开放或封闭构造的泛型类型。

    例如:

    using System;
    using System.Reflection;
    
    static class ReflectionTest
    {
        public static int Height;
        public static int Width;
        public static int Weight;
        public static string Name;
    
        public static void Write()
        {
        Type type = typeof(ReflectionTest); // Get type pointer
        FieldInfo[] fields = type.GetFields(); // Obtain all fields
        foreach (var field in fields) // Loop through fields
        {
            string name = field.Name; // Get string name
            object temp = field.GetValue(null); // Get value
            if (temp is int) // See if it is an integer.
            {
            int value = (int)temp;
            Console.Write(name);
            Console.Write(" (int) = ");
            Console.WriteLine(value);
            }
            else if (temp is string) // See if it is a string.
            {
            string value = temp as string;
            Console.Write(name);
            Console.Write(" (string) = ");
            Console.WriteLine(value);
            }
        }
        }
    }
    
    class Program
    {
        static void Main()
        {
        ReflectionTest.Height = 100; // Set value
        ReflectionTest.Width = 50; // Set value
        ReflectionTest.Weight = 300; // Set value
        ReflectionTest.Name = "ShekharShete"; // Set value
        ReflectionTest.Write(); // Invoke reflection methods
        }
    }
    
    Output
    
    Height (int) = 100
    Width (int) = 50
    Weight (int) = 300
    Name (string) = ShekharShete
    

    【讨论】:

    • 我还是不明白你为什么用它。如果可能的话,请给出一个简短的描述,这将有助于我更好地理解它。谢谢
    • 通用类型系统不会是 CTS,而不是 CLS?
    【解决方案5】:

    例如,您可以使用反射来实现插件系统。您只需在文件夹中查找所有 DLL,并通过反射检查它们是否实现了某个插件接口。这是我使用反射的主要目的,但我也使用它来实现通用的自制对象序列化,其中性能不是最关心的问题。

    【讨论】:

      【解决方案6】:

      如上所述,性能会受到影响。

      另一个很大的优势是您可以动态加载程序集、执行属性操作,即使您可能没有范围查看要更改的内容等。

      使用它的原因很多。如果您需要,这里是an introduction

      【讨论】:

        【解决方案7】:

        反射通常用于 IoC 容器。假设您要注册每个以“Controller”结尾的具体类。反射使这变得轻而易举。

        在单元测试类时,我还使用反射来操作私有字段。

        【讨论】:

          【解决方案8】:

          非常有用的 XmlSerialization 类依赖于反射。您不必自己处理反射来使用序列化,序列化类自己调用反射。但它有助于使用指导对象如何序列化的属性来标记您的代码。序列化类在运行时使用反射来读取这些属性。最后,这个过程看起来几乎是神奇的,在应用程序中只需要很少几行显式编码;正是反射使这种便利成为可能。

          XmlSerialization 本身很棒,不仅因为它是从应用程序创建数据文件的一种非常方便的方法,而且它还是一种非常简单的方法,可以生成程序内部数据模型的人类可读记录以进行调试。

          【讨论】:

            【解决方案9】:

            来自 C++ 并且需要一些简单的类层次结构,我可以说 is 关键字非常宝贵!

            class MenuItem : Item { }
            
            foreach(Item items in parent.ChildItems) {
                if (item is MenuItem) { /* handle differently */ }
            }
            

            附:顺便说一句,反射不是有点贵吗?

            【讨论】:

            • 这不是反射 :) 不,只有某些用例中的某些部分很慢。
            • 我的错,这是类型自省。
            • C++ 有类型自省,可以做同样的事情
            猜你喜欢
            • 1970-01-01
            • 2016-03-01
            • 2016-12-15
            • 2019-11-13
            • 2010-11-18
            • 2012-04-01
            • 2011-03-05
            • 2011-06-06
            • 2016-02-23
            相关资源
            最近更新 更多