PostSharp对字段定义的更改对使用lambda表达式不友好

本文关键字:lambda 不友好 表达式 字段 定义 PostSharp | 更新日期: 2023-09-27 18:09:28

我使用PostSharp的LocationInterceptionAspect来拦截类的字段和属性的调用。很明显,PostSharp在编译时更改了这样的类。但是,它妨碍了我的工作,而且问题不仅与依赖于此功能的代码的优雅性有关。

也就是说,我还使用lambda-expression来获取这些字段和属性的名称。下面是一个简化的示例来演示这一点:

    namespace Example
{
    using System.Linq.Expressions;
    public class Data
    {
        public string Field;
        public string Property { get; set; }
    }
    public class Process
    {
        public void Do()
        {
            string name1 = this.GetAttributeName<Data>(data => data.Field);
            // name1 = "<Field>k_OriginalField"
            string name2 = this.GetAttributeName<Data>(data => data.Property);
            // name2 = "Property"
        }
        private string GetAttributeName<DECLARING_TYPE>(Expression<Func<DECLARING_TYPE, object>> expression)
        {
            return (expression.Body as MemberExpression)?.Member?.Name;
        }
    }
}

这应该是显而易见的:我希望"k_OriginalField"为"Field"。这里有什么办法吗?

当然,我可以对这个字符串的格式做一些假设,并解析出我想要的值,但对我来说,这似乎是一个有点丑陋的解决方案。我确实需要保留字段定义和获取它们的名称,正如所演示的那样(它们的目的比这里看到的要复杂得多)。我不确定内部发生了什么,甚至与。net的构造lambda表达式,因为Data.Field显然存在(我通过反汇编也验证),但它已经变成了一个属性,我想我被交给了一个后台,而不是,我很困惑,为什么。

感谢您的宝贵时间。

编辑:我知道为什么会发生这种情况(我忘了早些检查):PostSharp也改变了这个"字段"成员的用法(但我仍然在质疑为什么),到这个:

string name1 = this.GetAttributeName<Data>(data => data.<Field>k_OriginalField);
// name1 = "<Field>k_OriginalField"

我发现这种用法替换很奇怪,因为PostSharp的拦截方面的全部意义是重定向执行流(同时允许自定义执行控制),所以调整调用以适应这些变化对我来说没有意义。Data类和Process类在同一装配体中;也许把它们分开会解决问题,但我不能轻易做到这一点,而且——再一次——作为一种解决方案,它看起来很难看。我希望PostSharp团队对此有什么看法

PostSharp对字段定义的更改对使用lambda表达式不友好

我不是PostSharp专家,但我不认为这是一个(大多数)一般情况下可以确定的问题。

想想看。PostSharp在构建时重写你的应用程序的部分类型系统,根据它在那一刻可以执行的任何静态分析,为所有相关的程序集,版本,以及到那时可访问的命名空间。

它无法看到未来并决定哪些候选重写应该被省略,因为客户端调用站点需要在构建时做出不同的假设,这些假设将在稍后的时间点发生,并且会在没有通过PostSharp的镜头或使用不同的镜头的情况下查看相同类型系统。

我认为,这就是为什么它必须假设,当它在你的类型上被调用时,所有的重写都必须以一种类型安全的方式在所有适用的地方得到遵守。

只是我的直觉。

HTH

,