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

问题描述 投票:3回答:1

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

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

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

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

myClassInstance.GetField("fieldName").Value

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

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

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

c# .net reflection
1个回答
3
投票

要获取实例字段,您必须执行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更方便。它还有一个优点,即单独的编译时类型(在运行时dynamic与编译时的object相同,编译器在编译时通过使用延迟而不是早期绑定来区别对待它)。因此,我们在object上没有一个公共表面,其中充满了非常罕见的情况的方法(事实上这种情况应该是罕见的;返回类型的速度,类型以及防止来自类型安全的不正确性的所有防范都应该是在任何可能的情况下都很受欢迎)并且也将dynamic作为返回类型也是好的,因为我们更有可能想要做更多这种后期绑定,这是我们第一次获得实例的方式。

© www.soinside.com 2019 - 2024. All rights reserved.