代码之家  ›  专栏  ›  技术社区  ›  Ian P

关于C#表达式树的建议

  •  3
  • Ian P  · 技术社区  · 16 年前

    我正在研究一个方法,该方法接受表达式树作为参数,以及类的类型(或实例)。

    其基本思想是,此方法将向用于验证的集合中添加某些内容。

    public interface ITestInterface
    {
        //Specify stuff here.
    }
    
    private static void DoSomething<T>(Expression<Func<T, object>> expression, params IMyInterface[] rule)
    {
        // Stuff is done here.
    }
    

    class TestClass
    {
        public int MyProperty { get; set; }
    }
    
    class OtherTestClass  : ITestInterface
    {
        // Blah Blah Blah.
    }
    
    static void Main(string[] args)
    {
        DoSomething<TestClass>(t => t.MyProperty, 
            new OtherTestClass());
    }
    

    我这样做是因为我希望传入的属性名是强类型的。

    1. PropertyInfo
    2. 我用的是特定的模式吗?
    3. 最后,对于任何关于我对自己所做工作的误解的建议或澄清,我们将不胜感激,并且/或者对于有关C#表达式树的资源或良好信息,我们也将不胜感激。

    谢谢

    伊恩

    什么例子 expression.Body.ToString() DoSomething方法中返回的字符串包含“Convert(t.MyProperty)”(如果从上述示例调用)。

    我确实需要它是强类型的,所以如果我更改属性名,它将不会编译。

    3 回复  |  直到 4 年前
        1
  •  3
  •   John Leidegren    16 年前

    我在很大程度上依赖于表达式树,将我想对当前应用程序执行的许多操作推送到编译时,即静态类型检查。

    我遍历表达式树,将它们转换为其他“有意义”的内容。

    有一件事我做了很多,那就是我不使用URL,而是使用类似MVC的方法来声明lambda函数,并将其转换为。。。解释,编译器将生成的表达式树转换为URL。当调用此URL时,我会执行相反的操作。这样,我就可以对断开的链接进行编译时检查,这对于重构和重载也非常有效。我认为以这种方式使用表达式树是很酷的。

    你可能想检查一下访问者模式,这是一个痛苦的开始,因为它在开始时没有多大意义,但它将所有东西联系在一起,这是解决编译器构造中类型检查的一种非常正式的方法。您也可以执行同样的操作,但不必进行类型检查,而是根据您的需要发出所需的内容。

    我目前正在极力反对的是构建一个简单的框架来翻译(或者实际上我应该说是解释)表达式树并发出JavaScript的能力。其思想是,编译器生成的表达式树将转换为与某些对象模型接口的有效JavaScript。

    令人兴奋的是,当我出错时,编译器总是能够告诉我最终结果只是一堆字符串,但重要的是这些字符串是如何创建的。他们进行了一些验证,这意味着什么。

    所以我喜欢这类东西,这就是元编程的全部内容,在你的程序中编写程序来执行程序。我说继续!

        2
  •  2
  •   Community Fabien Hure    7 年前

    从Expression.Body中收集PropertyInfo对象与 my solution

        3
  •  2
  •   Jason Jackson    16 年前

    我很感激你对这里的财产所做的一切。我遇到了这个难题。写作总是让人觉得很奇怪:

    DoSomething("MyProperty", new OtherClass());
    

    如果属性更改了名称,或者调用中的文本输入错误,那么就会出现问题。我学到的是,这可能需要通过测试来处理。特别是单元测试。我会编写单元测试来强制“DoSomething”调用正确工作。

    您可以尝试的另一件事是使用属性装饰属性,然后在构建类时针对类进行反射,以查找具有该属性的属性和加载规则。

    [DoSomething(typeof(OtherClass), typeof(OtherClass2))]
    public int MyProperty
    {
      get;
      set;
    }