2009-09-22 109 views

回答

31

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

Reflection的反对者会指出它比较慢,与静态代码执行相比是真实的 - 但是在整个.NET框架中使用了Reflection,并且假设它没有被滥用,它可以是一个非常强大的工具工具包。

一些有用的应用程序:

  • 确定的组件,其符合一个接口

  • 位置类型,从一个基极/抽象类派生的依赖关系,并通过属性搜索部件

  • (Smelly)testing - 如果你依赖一个不可测试的类(即它不允许你轻松地构建一个假的),你可以使用Reflection在类中注入假值 - 这不是很好,并不推荐,但它可以成为一个方便的工具。

  • 调试 - 倾出装组件,它们的引用,当前的方法等的列表...

+24

反射被几乎所有的测试框架用于开始,找到并执行测试... – 2009-09-22 06:00:57

30

有许多用途的反射:

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

但是,我最喜欢使用的反射之一是找到已标记属性的属性。

例如,我写了一些属性,用于标记我的类中哪些属性应该使用Lucene进行索引。在运行时,我可以查看任何类,只需查询类的“标记”属性即可找出需要索引的字段。

5

如上所述,表现会受到影响。

另一大优点就是可以动态加载组件,执行属性操作,即使你可能没有范围,看看有什么变化等

使用这个有很多原因。如果需要,这里是an introduction

20

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

+2

不知道你为什么downvoted,但我修正了:) – leppie 2009-09-22 05:53:59

+0

确实。反思是一个非常强大的资源,但它需要履行其职责,因此除非真正有必要,否则不应使用反思。 – Konamiman 2009-09-22 09:05:18

5

反射通常用于IoC容器。假设你想用“Controller”这个词注册每个具体的类。反射使这一块蛋糕。

我也使用反射操纵私人领域时,单元测试类。

0

由C++即将和已经需要一些简单的类层次结构,我可以说,is关键字是无价的!

class MenuItem : Item { } 

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

P.S.是不是反射稍微昂贵,顺便说一句?

+3

这不是反射:) 而且,在某些使用情况下只有某些部分很慢。 – leppie 2009-09-22 05:53:02

+0

我的不好,这是类型内省。 – 2009-09-22 22:08:13

+0

C++有类型自省,可以做同样的事情 – 2015-09-04 07:14:28

8

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

13

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

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

System.Type: class是.NET Reflection功能的主要类,也是访问元数据的主要方式。 System.Type类是一个抽象类,并且表示Common Type System(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 
2

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

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

相关问题