是否可以使用PostSharp向类添加方法?如果是,那么可以从其他类引用这些方法吗?

时间:2011-07-01 14:59:14

标签: c# postsharp aop

假设我有一个班级Abc

class Abc {
}

我想在外部添加一些方法m()。我想这可能有可能做到这一点,虽然我不知道如何。假设有可能这样做,那么让我们说从现在开始Abc确实有m()方法。

现在,想象一下我有其他课程Def

class Def {
    public void x(Abc abc) {
        abc.m();
    }
}

此代码是否会与PostSharp一起运行?对于更分散注意力的读者来说,问题在于,在标准的C#类程序中,我们的编译器可能不知道Abc类具有m()方法。

我的直觉是,这不适用于PostSharp。我错了吗?

2 个答案:

答案 0 :(得分:3)

(如果我的PostSharp解决方案还不够,你可以使用DLR来完成吗?)

是的,你可以。您将在实例作用域方面使用introductionmember属性。最好的办法是使用postshsrp实现一个接口,然后引用你的目标类作为该接口来公开该方法。您还可以使用Post.Cast<>()在设计时访问它。

以下是执行此操作的两种方法。第一个是通过接口,第二个是使用存根。

方法1 - 界面

public class Program
    {
        static void Main(string[] args)
        {
            Customer c = new Customer();
            var cc = Post.Cast<Customer, ISomething>(c);

            cc.SomeMethod();
        }
    }

    public interface ISomething
    {
        void SomeMethod();
    }

    [AddMethodAspect]
    public class Customer
    {

    }

    [Serializable]
    [IntroduceInterface(typeof(ISomething))]
    public class AddMethodAspect : InstanceLevelAspect, ISomething
    {

        #region ISomething Members

        public void SomeMethod()
        {
            Console.WriteLine("Hello");
        }

        #endregion
    }

方法2 - 存根

public class Program
    {
        static void Main(string[] args)
        {
            Customer c = new Customer();
            c.SomeMethod();
        }
    }

    [AddMethodAspect]
    public class Customer
    {
        public void SomeMethod() { }

    }

    [Serializable]
    public class AddMethodAspect : InstanceLevelAspect
    {
        [IntroduceMember(OverrideAction = MemberOverrideAction.OverrideOrFail)]
        public void SomeMethod()
        {
            Console.WriteLine("Hello");
        }
    }

更多信息 为了防止使用Cast&lt;&gt;()函数存在一些问题,它不会进行实际的转换。编译结果如下:

private static void Main(string[] args)
        {
            Customer c = new Customer();
            ISomething cc = c;
            cc.SomeMethod();
        }

答案 1 :(得分:0)

如果该类位于不同的程序集中,则可以执行此操作。

另一方面,如果类在同一个模块中,那么你是对的,C#编译器不会编译它。为什么不在C#中实现这样的m(),然后用PostSharp替换实现?

class Abc
{
   public void m()
   {
      throw new NotImplementedException ();
   }
}

编辑:

如果将m()放在界面中,然后使用PostSharp在您的类上实现界面,该怎么办?然后,您可以通过强制转换到该接口来调用该方法。

interface IM
{
   void m();
}

class Def {
    public void x(Abc abc) {
       if (abc is IM)
        ((IM) abc).m();
    }
}