我可以在不使用反射的情况下获取类中字段或属性的 PropertyInfo 吗?

Posted

技术标签:

【中文标题】我可以在不使用反射的情况下获取类中字段或属性的 PropertyInfo 吗?【英文标题】:Can I get PropertyInfo for a field or property in a class without using reflection? 【发布时间】:2021-06-14 11:10:00 【问题描述】:

我尝试使用表达式四处搜索,但找不到可以在不使用反射的情况下访问类的字段或属性的内容。

基本上,我会在运行时得到一个字符串,我知道该字符串将是类的属性,但我需要验证它确实是该类中的属性。

例如如果我有课:

class Test  string a; public string b get;set; 

我在运行时获得了字符串值ab,我需要验证它们是否存在于Test 类中

到目前为止,我通过研究知道我可以做到:

string one = "a";
string two = "b";
PropertyInfo result1 = typeof(Test).GetProperty(one);
PropertyInfo result2 = typeof(Test).GetProperty(two);

但是这段代码使用了反射。我想知道是否有某种方法可以在不使用反射的情况下做到这一点?

我可以使用表达式来做到这一点吗?

【问题讨论】:

我很确定如果没有反思,这是不可能的。我看到的唯一方法是缓存反射的结果值,以避免对同一类型进行多次反射调用。即使是表达式也必须使用反射来收集信息。如果您尝试使用 propertyInfo.GetValue(instance, null) 从属性中收集值,则可以使用表达式树提高性能,但您仍然需要反射来构建此表达式。一旦构建它就可以缓存。 【参考方案1】:

使用表达式,您可以通过以下方式获得PropertyInfo

    Test t = new Test();
    t.b = "sadf";
    Expression<Func<string>> exp = () => t.b;
    var memExp = exp.Body as MemberExpression;
    MemberInfo member = memExp.Member;
    PropertyInfo property = (PropertyInfo)member;
    Console.WriteLine(property.GetValue(t));

这将输出变量的属性值(示例中为sadf)。但是你想达到什么目的?为什么不从Type 收集PropertyInfo?因为很有可能在幕后,这段代码会像你一样使用反射(就像 LINQ 仍然使用循环一样,但程序员只是看不到它)。

【讨论】:

如果您只有一个包含属性名称的字符串,如何创建表达式() =&gt; t.b?我只看到Expression.Property(..., typeof().GetProperty(&lt;str&gt;)) 仍在使用反射。 @SebastianSchumann,是的,你是对的。我想从字符串中获取。所以这意味着,没有反射是不可能的。

以上是关于我可以在不使用反射的情况下获取类中字段或属性的 PropertyInfo 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Java反射 在只知道类名的情况下,怎样给其中的私有属性赋值

如何在不使用类名作为范围的情况下获取类中成员函数的地址?

c#的属性和反射,大约是啥回事

Laravel 6 Backpack 4.0:如何在 FormRequest 类中获取当前页面 ID,或者我可以在不使用 FormRequest 类的情况下获得吗?

如何在不触摸或点击文本字段的情况下从动态创建的 UITextField 获取文本(禁用用户交互)?

访问修饰符也会影响反射吗?