C# 为什么推荐在 .NET 中使用反射?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1458256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 17:44:54  来源:igfitidea点击:

Why is the use of reflection in .NET recommended?

c#.netreflection

提问by Jaswant Agarwal

Is it definitely a good practice to use it?

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

What are some possible situations in a project that need reflection?

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

采纳答案by STW

The main value of Reflection is that it can be used to inspect assemblies, types, and members. It's a very powerful tool for determining the contents of an unknown assembly or object and can be used in a wide variety of cases.

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

Opponents of Reflection will cite that it is slow, which is true when compared to static code execution--however Reflection is used throughout the .NET framework, and provided that it's not abused it can be a very powerful tool in the toolkit.

Reflection 的反对者会说它很慢,这与静态代码执行相比是正确的——但是在整个 .NET 框架中都使用了 Reflection,并且只要它不被滥用,它就可以成为工具包中一个非常强大的工具。

Some useful applications:

一些有用的应用:

  • Determining dependencies of an assembly

  • Location types which conform to an interface, derive from a base / abstract class, and searching for members by attributes

  • (Smelly) testing - If you depend on a class which is untestable (ie it doesn't allow you to easily build a fake) you can use Reflection to inject fake values within the class--it's not pretty, and not recommended, but it can be a handy tool in a bind.

  • Debugging - dumping out a list of the loaded assemblies, their references, current methods, etc...

  • 确定程序集的依赖关系

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

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

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

回答by Esteban Araya

There are many uses for reflection:

反射有很多用途:

  1. Iterating through properties in an object.
  2. Invoking a method that's defined at runtime.
  3. Many other other on the same vein.
  1. 遍历对象中的属性。
  2. 调用在运行时定义的方法。
  3. 同脉的其他许多人。

However, one of my favorite uses of reflection is to find properties that have been marked with attributes.

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

For example, I've written attributes that mark which properties in my classes should be indexed using Lucene. At runtime, I can look at any class, and figure out what fields need to get indexed by just querying the class for "marked" properties.

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

回答by Kyle Rozendo

As mentioned above, performance will take a hit.

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

Another great advantage is that you can dynamically load assemblies, perform property manipulation even though you may not have the scope to see what to change, etc.

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

The reasons to use this are plenty. Here is an introductionif you need.

使用它的原因很多。如果需要,这里有一个介绍

回答by Samantha Branham

Reflection is just a way of investigating objects during run-time. You shouldn't use it if you don't need to do just that.

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

回答by Scott Muc

Reflection is commonly used in IoC containers. Let's say you want to register every concrete class the ends with the word "Controller". Reflection makes that a piece of cake.

反射通常用于 IoC 容器。假设你想用“Controller”这个词注册每个具体的类。反射使这成为小菜一碟。

I've also used reflection to manipulate private fields when unit testing classes.

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

回答by Nick Bedford

Coming from C++ and having needed some simple class hierarchies, I can say that the iskeyword is invaluable!

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

class MenuItem : Item { }

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

P.S. Isn't reflection slightly expensive, btw?

PS 是不是反射有点贵,顺便说一句?

回答by rslite

You can use reflection to implement a system of plugins for example. You just look for all DLL's in a folder and through reflection check if they implement a certain plugin interface. This is the main purpose for which I used reflection, but I also used it to implement a generic home-brew object serialization, where performance was not the greatest concern.

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

回答by SHEKHAR SHETE

Reflectionallows an application to collect information about itself and also to manipulate on itself. It can be used to find all types in an assembly and/or dynamically invoke methods in an assembly.

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

System.Reflection:namespace contains the classes and interfaces that provide a managed view of loaded types, methods, and fields, with the ability to dynamically create and invoke types; this process is known as Reflection in .NET framework.

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

System.Type:class is the main class for the .NET Reflection functionality and is the primary way to access metadata. The System.Type class is an abstract class and represents a type in the Common Type System (CLS).

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

It represents type declarations: class types, interface types, array types, value types, enumeration types, type parameters, generic type definitions, and open or closed constructed generic types.

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

Eg:

例如:

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

回答by WayneMV

The very useful XmlSerialization class relies on reflection. You don't have to deal with reflection yourself to use serialization, the serialization classes invoke reflection themselves. But it helps to tag your code with Attributes that guide how objects are serialized. The serialization classes use reflection at runtime to read those attributes. In the end, the process seems almost magical, requiring very few lines of explicit coding in a application; it's reflection that makes that convenience possible.

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

XmlSerialization itself is awesome not only because it is a very convenient way to create data files from an application, it's also a very easy means of generating human readable records of a program's internal data model for debugging purposes.

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