我对C#中的Reflection还是很陌生,我想我知道如何使用它来解决一些问题。

但是,令我感到困惑的是诸如GetProperty()或GetField()之类的方法的语法。

要获取实例字段,您必须执行typeof(MyClass).GetField("fieldName").GetValue(myClassInstance)。这不是最直接的事情。

通过使用诸如扩展方法之类的方法来获取实例字段或属性是否更有意义?就像是:

myClassInstance.GetField("fieldName").Value


并使用前面的示例来处理诸如静态字段/属性/方法之类的事情。

这比第一个示例(必须通过您的类实例)更自然。

再次,我是反射的新手,因此可能存在一些我忽略的缺点。

最佳答案

要获取实例字段,您必须执行typeof(MyClass).GetField("fieldName").GetValue(myClassInstance)。这不是最直接的事情。


好吧,不完全是。要获取实例字段,您必须执行fieldInfo.GetValue(myClassInstance)

当然,从myClassInstanceMyClass的编译时(实际上是编码时)知识开始,就意味着您获得fieldInfo的方式是通过typeof(MyClass).GetField("fieldName"),但随后人们只会做myClassInstance.fieldName或者如果必须进行强制转换((MyClass)myClassInstance).fieldName,则更容易,更快捷且更不易出错。

当我们不能仅仅执行myClassInstance.fieldName时,反射是很有用的,因为我们仅在运行时获得了Type和/或FieldInfo。然后,我们需要的灵活性是让我们处理编译时我们所知或不知的各种情况。

现在,完全有可能创建类型和方法(实例或扩展)以使myClassInstance.GetField("fieldName").Value起作用。但是那会有用吗?

首先,如上所述,如果在编译时知道myClassInstance的类型,则毫无意义。但是,此GetField()方法应适用于哪种类型?编译时类型显然是没有意义的,但是它应该是运行时类型(通过调用GetType()可以找到的类型)吗?那可能是最常用的类型,但是我们可能希望强制查找基于特定的基本类型(或接口类型-显然不是在查找字段的情况下,而是在方法,属性和事件方面),因此,我们在此方面失去了灵活性,仅针对当前可解决的特定案例子集有所收获。

因此,尽管在某些情况下添加此功能很有用,但在其他情况下仍需要当前的API。它只能是便捷API,而不能是主要API。

实际上,我们拥有该便捷API,因为dynamic可以为我们提供。

((dynamic)myClassInstance).fieldName


这使我们能够在fieldName的运行时类型上获取或设置名为myClassInstance的字段,并且通常比您提出的API更方便。它还具有单独的编译时类型的优点(在运行时dynamicobject相同,在编译时,编译器通过使用后期绑定而不是早期绑定来区别对待)。因此,在非常罕见的情况下(而且确实应该是罕见的情况),我们没有充分利用object的方法公开露面;实际上,速度,返回类型的输入以及最重要的是防止来自类型安全性的不正确性是很重要的。 (尽可能在可能的情况下受到青睐)),并且也将dynamic作为返回类型也很不错,因为当我们第一次获取实例时,我们更有可能希望做更多这种后期绑定。

关于c# - 为什么反射的GetProperty()或GetField()不是实例或扩展方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45942917/

10-09 04:36