2011-07-01 1 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 개의 mthod를 포함하도록 업데이트되었습니다. –

답변

0

클래스가 다른 어셈블리에 있으면 수행 할 수 있습니다.

반면에 클래스가 동일한 모듈에 있으면 올바른 것으로 C# 컴파일러가 컴파일하지 않습니다. m()을 C#으로 구현하지 않은 다음 구현을 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

는 (내 PostSharp 솔루션이 충분하지 않은 경우 아마 당신은 달성하기 위해 DLR을 사용할 수 있습니까?)

예하실 수 있습니다. 인스턴스 스코프 된 aspect에서 introdumember 애트리뷰트를 사용할 것이다. 가장 좋은 방법은 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"); 
     } 
    } 

추가 정보 그냥 경우에 캐스트 <>를 사용하여 몇 가지 문제는()가 함수가 아니라 실제 캐스팅을 수행합니다. 컴파일 결과는 다음과 같습니다.

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