2011-07-01 116 views
4

比方说,我有一个类Abc是否可以使用PostSharp向类中添加方法?如果是,是否有可能从其他类中引用这些方法?

class Abc { 
} 

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

现在,想象我有其他类Def

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

将运行与PostSharp这个代码?对于更分心的读者来说,问题在于,在一个标准的C#类程序中,我们的编译器可能不知道Abc类有一个m()方法。

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

+0

更新了我的答案,其中包括2个方法来引入方法。 –

回答

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(); 
    } 
} 
+1

因为那样它就会挫败只有在方面而不是在课堂上才有我的交叉担忧的整个目的!添加/删除问题将意味着必须更改所有类。 –

+0

如果您直接调用某个方法,那么您如何交叉问题?如果你把'm()'放在一个接口中,那么用PostSharp来实现你的类的接口呢?然后,您可以通过投射到该界面来调用该方法。 –

+0

我没有看到从一个方面进行方法调用有什么问题。想象一下ApplyBonus方面,它具有与银行系统奖金相关的所有逻辑。 –

3

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

当然可以。您可以在实例作用域方面使用引入成员属性。你最好的选择是使用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 <>()功能,它不会做实际的演员。编译结果如下:

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