【问题标题】:PostSharp: OnMethodBoundaryAspect on derived class's constructorPostSharp:派生类的构造函数上的 OnMethodBoundaryAspect
【发布时间】:2009-12-11 12:24:15
【问题描述】:

我有一个方面可以在异常时向控制台写入内容。 我有一个在其构造函数上引发异常的基类,以及一个在其构造函数上具有切面的派生类。

我希望构造函数的派生类方面会捕获基类异常,但它不会。

这是设计使然吗?这是一个错误吗? 还是我做错了什么?

这里是示例代码(控制台应用程序):

[Serializable]
public class OnExceptionWriteAspect : OnMethodBoundaryAspect
{
    public override void OnException(MethodExecutionEventArgs eventArgs)
    {
        Console.WriteLine("Exception catched on Aspect.");
    }
}

public class BaseClass
{
    public BaseClass()
    {
        throw new Exception();
    }
}

public class DerivedClass : BaseClass
{
    [OnExceptionWriteAspect]
    public DerivedClass()
        : base()
    {

    }
}

public class Program
{
    static void Main(string[] args)
    {
        try
        {
            new DerivedClass();
        }
        catch
        {
            Console.WriteLine("Exception catched on Main.");
        }
    }
}

输出是:

在 Main 上捕获了异常。

【问题讨论】:

    标签: c# .net inheritance constructor postsharp


    【解决方案1】:

    这是设计使然。无法在对基本构造函数的调用周围放置异常处理程序。 MSIL 代码将无法验证。

    【讨论】:

    • 假设我仍然想要上面描述的功能,而不触及基类代码,这可能吗?
    • 理论上,这是可能的,但您的程序集将不再是可验证的。这并不意味着它不会运行,但它需要完全信任。你可以通过直接玩 PostSharp Core 来做到这一点。 PostSharp 老挝不允许这样做。
    【解决方案2】:

    如果您通过反射器查看 DerivedClass,您会发现 Aspect 仅包装了 DerivedClass 的构造函数。

    public class DerivedClass : BaseClass
    {
        // Methods
        public DerivedClass()
        {
            MethodExecutionEventArgs ~laosEventArgs~1;
            try
            {
                ~laosEventArgs~1 = new MethodExecutionEventArgs(<>AspectsImplementationDetails_1.~targetMethod~1, this, null);
                <>AspectsImplementationDetails_1.MyTest.OnExceptionWriteAspect~1.OnEntry(~laosEventArgs~1);
                if (~laosEventArgs~1.FlowBehavior != FlowBehavior.Return)
                {
                    <>AspectsImplementationDetails_1.MyTest.OnExceptionWriteAspect~1.OnSuccess(~laosEventArgs~1);
                }
            }
            catch (Exception ~exception~0)
            {
                ~laosEventArgs~1.Exception = ~exception~0;
                <>AspectsImplementationDetails_1.MyTest.OnExceptionWriteAspect~1.OnException(~laosEventArgs~1);
                switch (~laosEventArgs~1.FlowBehavior)
                {
                    case FlowBehavior.Continue:
                    case FlowBehavior.Return:
                        return;
                }
                throw;
            }
            finally
            {
                <>AspectsImplementationDetails_1.MyTest.OnExceptionWriteAspect~1.OnExit(~laosEventArgs~1);
            }
        }
    }
    
    public BaseClass()
    {
        throw new Exception();
    }
    

    如果您想处理 Aspect Inheritance,请查看使用 MulticastAttributeUsage

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 2011-12-29
      • 1970-01-01
      • 2018-07-16
      • 1970-01-01
      • 2016-07-19
      • 2016-10-06
      相关资源
      最近更新 更多