如何从PropertyInfo获取Getter支持字段? [英] How to get Getter backing field from PropertyInfo?

查看:209
本文介绍了如何从PropertyInfo获取Getter支持字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的课程如下:

class Foo : PropertyChangedBase {
    private int _property;

    public int Property {
       get { return _property; }
       set { OnAssignPropertyChanged("Property", () => _property, value); }
}

PropertyChangedBase通过以下方法实现INotifyPropertyChanged:

    protected void OnAssignmentPropertyChanged<T>(string propertyName, Expression<Func<T>> fieldExpression, T value)
    {
        var get = fieldExpression.Compile();
        if (get().Equals(value))
        {
            return;
        }

        //  invoke set property method
        SetProperty(fieldExpression, value);
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private void SetProperty<T>(Expression<Func<T>> fieldExpression, T value)
    {
        if (fieldExpression == null)
        {
            throw new ArgumentNullException(nameof(fieldExpression));
        }

        var memberExpression = fieldExpression.Body as MemberExpression;
        if (memberExpression == null)
        {
            throw new ArgumentException("fieldExpression");
        }

        var field = memberExpression.Member as FieldInfo;
        if (field == null)
        {
            throw new ArgumentException("fieldExpression");
        }

        field.SetValue(this, value);
    }

我想打:

OnAssignPropertyChanged(() => Property, value);

这将起作用的唯一方法是,如果我可以获取属性getter的后备字段,然后将其传递给SetProperty.是否可以通过属性get方法获取FieldInfo或目标成员?

The only way this will work is if I can get the backing field for the property getter and then pass that to SetProperty. Is it possible to get the FieldInfo or target member from the property get method?

推荐答案

作为一般性回答,可以的,至少在受控条件下可以.但是,只有在您绝对确定自己在做什么并且只有有限的支持的情况下,才应该执行此操作,因为在某些情况下您将无法处理.

As a general answer, yes you can do, at least under controlled conditions. But the only case you should do this is when you are absoluty sure what you are doing and only with limited support, because there will be cases you can not handle.

在这里查看答案:使用反射查找所有属性引用.目标稍有不同,但是查找字段引用的方法相似.既然答案已经包含了必要的代码,我将概述其发展方式:

Have a look at the answer here: Find all property references using reflection. The target is a bit different but the approach is similar for finding field references. Since the answer there already includes the necessary code i will just outline the way to go:

.Net中的所有元数据项均由令牌引用.要在方法中使用令牌,必须解析 MethodBody (跳过所有您不会检查的内容),然后 BitConverter 从流中读取令牌以对其进行解析.

All metadata items in .Net are referenced by tokens. To get tokens used inside a method you have to parse the MethodBody (by skipping all the things you wont inspect) and then resolve the found tokens in their module. Remember to use the BitConverter when reading the tokens from the stream to resolve them.

但现在是不利的一面;唯一真正可以安全地使用它来查找属性getter的后备字段的时间是,当您找到一个简单的get方法时,该方法具有定义良好的操作码序列(如Ldfld,Ret或类似名称).也许您可以定义C#编译器将为简单和自动实现的属性发出的一些模式.如果发现任何不同,则没有其他方法可以退出并引发异常,因为getter可以包含任何代码. 与往常一样,仅使用白名单方法,检查期望的条件并在其他情况下抛出异常,否则迟早会遇到NullReferenceException.

But now to the down side; the only time you can really safely use this to find the backing fields of a properties getter, is when you find a simple get method, with a well defined opcode sequence like Ldfld, Ret or something like that. Maybe you can define a few patterns that the C# compiler will emit for simple and autoimplemented properties. If you find anything different there is no other way as to resign and throw an exception, because the getter could contain any code. Like always with reflection, only use whitelist approaches, check for the conditions you expect and throw exeptions in any other case or you will run into a NullReferenceException sooner or later.

如果这是值得的,那么您就可以决定要解决的麻烦,但是从.Net 2.0开始,您通常可以这样做,甚至不需要花哨的外部lib.

If this is worth the trouble is for you to decide, but in general you could do this since .Net 2.0 and do not even need a fancy external lib.

这篇关于如何从PropertyInfo获取Getter支持字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆