【问题标题】:How to replace auto-implemented c# get body at runtime or compile time?如何在运行时或编译时替换自动实现的 c# get body?
【发布时间】:2010-06-17 06:29:33
【问题描述】:

我整晚都在试图解决这个问题,但我想我对 .Net 框架的了解并不那么深入,而且问题也不完全是谷歌,但如果我能在正确的方向我确信我可以以一种或另一种方式实现它。

我希望能够声明一个用自定义属性装饰的属性:

public MyClass {

    [ReplaceWithExpressionFrom(typeof(SomeOtherClass))]
    public virtual bool MyProperty { get; }

}

public SomeOtherClass : IExpressionHolder<MyClass, bool> {

    ...
}

public interface IExpressionHolder<TArg, TResult> {
    Expression<Func<TArg, TResult>> Expression { get; }
}

然后不知何故 - 这是我无法弄清楚的部分 - 用一段自定义代码替换自动生成的 getter 实现,例如:

Type expressionHolderType = LookupAttributeCtorArgTypeInDeclarationOfPropertyWereReplacing();
return ReplaceWithExpressionFromAttribute.GetCompiledExpressionFrom(expressionHolderType)(this);

我不知道该怎么做的主要事情是替换get的自动实现。

首先想到的是PostSharp,但这是一个比我关心的更复杂的依赖关系。我更喜欢一种不使用附加到构建的后处理来编写代码的方法(我认为这就是 PostSharp 无论如何都会下沉它的钩子的要点)。

我不太确定的另一部分是如何检索传递给 ReplaceWithExpressionFrom 属性的特定实例化的类型参数(它装饰我要替换其主体的属性;换句话说,如何我得到 typeof(SomeOtherClass) 我正在编码获取身体替换)。我计划缓存来自 IExpressionHolder 的具体实例的编译表达式,因为我不想在每次检索属性时都这样做。

我认为这只是得到成为可能。至少我认为我应该能够在程序集中搜索任何用该属性装饰的方法,并以某种方式代理该类,或者只是替换 IL 或 .. 什么?而且我想让集成尽可能顺利,所以如果这可以在不显式调用注册或初始化方法的情况下完成,那将是非常棒的。

谢谢!

【问题讨论】:

    标签: .net linq lambda custom-attributes dynamic-programming


    【解决方案1】:

    也许我会为此投反对票,但您为什么要为此购买房产?

    您似乎想要的是一个虚拟通话。为什么不简单地继承 MyClass 并实现虚拟调用?

    或者您可以使用代理字典来进行适当的函数调用。

    【讨论】:

    • 实际上,在以前的工作的基础上,我计划实现一个小框架,这样当 MyClass.MyProperty(在我的示例中)用于 LINQ 查询时,提供程序会用表达式替换方法调用,因此它可以转换为SQL。其他人已经实现了这一点,我只是想实现一种更简洁的方式将它附加到我的域类,而不是之前的所有示例。
    • 这就是为什么属性的实现需要保留为一个Expression对象。之前的所有示例都要求程序员编写 get 代码以调用该属性,因此一个人可能最终会在 get 中使用一种实现,而在再次使用 IQueryable 的 Expression 中使用另一种实现。并不是说我很想防止这种情况发生,因为我只是想使用这种清洁剂。
    • 我之前尝试扩展的工作主线可以在mathgeekcoder.blogspot.com/2008/07/…找到
    • @qes,和我想在我的项目中做的一样——刚刚在 ORM 和应用程序之间创建了抽象层。我的域类型是接口,而 Linq 的具体实现需要使用 ExpressonVisitor,然后用具体实现替换域接口的表达式...
    【解决方案2】:

    似乎无法在运行时替换方法的实现。

    它可以在编译时被替换,就像 PostSharp 对 IL 重写和编织所做的那样。

    此外,生成的代理可以覆盖虚拟成员 - 尽管这需要通过一个集中点来集中创建对象,在该点可以分发代理来代替真实的东西(a la NHibernate)。

    【讨论】:

      猜你喜欢
      • 2014-05-22
      • 2021-02-06
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 2014-08-06
      • 2014-04-11
      • 1970-01-01
      相关资源
      最近更新 更多