2011-09-24 3 views
6

두 클래스 모두 이벤트를 발생시키는 다른 개인 클래스를 포함합니다. 이 두 클래스는 이러한 이벤트를 클라이언트에 다시 발생시킵니다. 당신이 볼 수 있듯이동일한 중복 이벤트가있는 두 클래스를 어떻게 리팩토링합니까?

public class FirstClass 
{ 
    public delegate void FooEventHandler(string foo); 
    public delegate void BarEventHandler(string bar); 
    public delegate void BazEventHandler(string baz); 

    public event FooEventHandler Foo; 
    public event BarEventHandler Bar; 
    public event BazEventHandler Baz; 

    private PrivateObject privateObject; 

    public FirstClass() 
    { 
     privateObject.Foo += FirstClass_Foo; 
     privateObject.Bar += FirstClass_Bar; 
     privateObject.Baz += FirstClass_Baz; 
    } 

    private void FirstClass_Foo(string foo) 
    { 
     if (Foo != null) 
     { 
      Foo(foo); 
     } 
    } 

    private void FirstClass_Bar(string bar) 
    { 
     if (Bar != null) 
     { 
      Bar(bar); 
     } 
    } 

    private void FirstClass_Baz(string baz) 
    { 
     if (Baz != null) 
     { 
      Baz(baz); 
     } 
    } 
} 

, 나는 개인 개체에서 다시 제기 이벤트에 있습니다

불행하게도, 두 클래스의 각이 동일한 코드가 있습니다. 그것은 불필요합니다. 내가 상속을 사용하고 기본 클래스에서이 중복 코드를 삽입 시도했지만 내가 좋아지고 오류가 계속 :

이벤트 'BaseClass.Foo는'에만 + = 또는 왼쪽에 나타날 수

- = (경우를 제외하고 형식 내에서 사용)

누구든지이 중복 코드를 제거하는 방법을 알고 있습니까?

답변

5

래퍼 속성으로 개인 개체의 이벤트를 표시하는 방법은 무엇입니까? 당신은 C#을 속성을 잘 알고있는 경우

public class ExternalClass 
{ 
    private InternalClass _internalObject = new InternalClass(); 

    public event InternalClass.someDelegate SomeEvent 
    { 
     add 
     { 
      _internalObject.SomeEvent += value; 
     } 
     remove 
     { 
      _internalObject.SomeEvent -= value; 
     } 
    } 
} 

public class InternalClass 
{ 
    public delegate void someDelegate(string input); 
    public event someDelegate SomeEvent; 
} 

에서와 같이 당신은 아마 이미 getset 키워드를 알고있다. add/remove 키워드는 기본적으로 동일한 속성이며 속성에 값을 추가하거나 제거하려고 할 때만 해고됩니다.

따라서 위임자를 ExternalClass.SomeEvent에 등록 (취소)하라는 명령을 내리면 실제로는 InternalClass.SomeEvent 이벤트에 등록됩니다.

C# 속성에 익숙하지 않은 경우 http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx이 도움이됩니다.

+2

당신은 더 나은 이벤트의 이름의 onEvent 사용하지 것입니다. OnEvent는 이벤트를 발생 시키거나 실행하는 메소드의 표준 이름입니다. 그렇지 않으면 귀하의 답변에 동의합니다. –

+0

정정 해 주셔서 대단히 감사합니다. – Andrea

+0

Andrea : 답장을 보내 주셔서 감사합니다! 불행히도이 코드가 정확히 무엇을하는지에 따라 약간의 문제가 있습니다. 나는 심지어'add'와'remove' 키워드에 대해서 들어 보지 못했습니다. o_O이 코드를 조금 설명해 주시겠습니까? –

0

나는 이것이 당신에게 도움이 될 것이라고 생각합니다. 공용 인터페이스를 사용하면 PrivateObject를 내부에 유지할 수 있습니다. 유일한 다른 트릭은 생성자에서 RegisterIFooEvents를 호출해야한다는 것입니다. 콘솔 응용 프로그램에서

public interface IFooEvents 
{ 
    event BaseClass.FooEventHandler Foo; 
    event BaseClass.BarEventHandler Bar; 
    event BaseClass.BazEventHandler Baz; 
} 

internal class PrivateObject : IFooEvents 
{ 
    public event BaseClass.FooEventHandler Foo; 
    public event BaseClass.BarEventHandler Bar; 
    public event BaseClass.BazEventHandler Baz; 

    public void ChangeFoo(string foo) 
    { 
     if (Foo != null) 
     { 
      Foo(foo); 
     } 
    } 
} 

public abstract class BaseClass : IFooEvents 
{ 
    public delegate void BarEventHandler(string bar); 
    public delegate void BazEventHandler(string baz); 
    public delegate void FooEventHandler(string foo); 

    private IFooEvents _fooEvents; 

    public event FooEventHandler Foo 
    { 
     add { _fooEvents.Foo += value; } 
     remove { _fooEvents.Foo -= value; } 
    } 

    public event BarEventHandler Bar 
    { 
     add { _fooEvents.Bar += value; } 
     remove { _fooEvents.Bar -= value; } 
    } 

    public event BazEventHandler Baz 
    { 
     add { _fooEvents.Baz += value; } 
     remove { _fooEvents.Baz -= value; } 
    } 

    protected void RegisterIFooEvents(IFooEvents fooEvents) 
    { 
     _fooEvents = fooEvents; 
    } 
} 

public class FirstClass : BaseClass 
{ 
    private readonly PrivateObject _privateObject; 

    public FirstClass() 
    { 
     _privateObject = new PrivateObject(); 
     RegisterIFooEvents(_privateObject); 
    } 

    public void ChangeFoo(string foo) 
    { 
     _privateObject.ChangeFoo(foo); 
    } 
} 

테스트 실행 :

class Program 
{ 
    static void Main(string[] args) 
    { 
     var class1 = new FirstClass(); 
     class1.Foo += EventRaised; 
     class1.ChangeFoo("TEST"); 

    } 

    static void EventRaised(string arg) 
    { 
     Console.WriteLine(arg); 
    } 
} 
관련 문제