为什么Reflection的GetProperty()或GetField()不是实例或扩展方法?

时间:2017-08-29 15:24:32

标签: c# .net reflection

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

然而,我觉得令人困惑的是GetProperty()或GetField()等方法的语法。

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

通过使用扩展方法之类的东西获取实例字段或属性会不会更有意义?类似的东西:

myClassInstance.GetField("fieldName").Value

并使用前面的示例来处理静态字段/属性/方法。

它感觉比第一个例子更自然,你必须传递你的类实例。

同样,我是Reflection的新手,所以我可能会忽略一些缺点。

1 个答案:

答案 0 :(得分:3)

  

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

嗯,不太好。要获取实例字段,您必须执行fieldInfo.GetValue(myClassInstance)

当然,从myClassInstanceMyClass的编译时(实际上是编码时)知识开始,意味着fieldInfo获得typeof(MyClass).GetField("fieldName")的方式是{{1然而,只有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更方便。它还有一个优点,即单独的编译时类型(在运行时dynamic与编译时的object相同,编译器在编译时通过使用后期绑定而不是早期绑定来区别对待它) 。所以我们在object的公共表面上没有充分的方法来处理非常罕见的情况(事实上应该很少见的情况;速度,返回类型的类型和最重要的是防止来自类型安全的不正确性,尽可能地受到支持)并且也将dynamic作为返回类型,这是好的,因为我们更可能想要做更多这种类型的在第一次获得实例时我们如何获得后期绑定。