2011-01-25 3 views
2

동적 객체에 이벤트 처리기를 추가했습니다. 그러나, 나는 그들을 제거 할 수 없습니다. 를 제거 할 때 DynamicObject에서 이벤트 제거

dynamic d = new MyDynamicObject(); 
d.MyEvent += new EventHandler(this.MyHandler); 
d.MyEvent -= new EventHandler(this.MyHandler); 

나는 이벤트 처리기를 추가

, 나는 그러나, 호출 인수로 핸들러 TrySetMember에 도착, 값은 null입니다. 그것이 null이라면 특정 이벤트에 대한 핸들러의 내부 스토리지에서 어떤 핸들러를 제거해야하는지 어떻게 알 수 있습니까?

답변

0

나는 당신이 그 주위에 당신의 new EventHandler에 대한 참조를 유지하고 제거 할 필요가 있다고 생각 :

var MyEventHandler = new EventHandler(this.MyHandler); 
d.MyEvent += MyEventHandler; 
d.MyEvent -= MyEventHandler; 
+0

아니, 그 차이는 없습니다. 값은 여전히 ​​null입니다. – fettsnoken

+0

오, 예 - 죄송합니다. 예를 들어 생성 된 코드에서 패턴을 많이 보았습니다. WCF에서. – Rup

1

하드 문제가 볼 수있는 미리보기없이 될 일을 추측 할 수 있습니다. 이 추가가 정적 이벤트처럼 작동하지 않기 때문에,

using System; 
using System.Dynamic; 

class Program { 
    static void Main(string[] args) { 
     dynamic obj = new MyDynamicObject(); 
     obj.MyEvent += new EventHandler(handler); 
     obj.MyEvent(null, EventArgs.Empty); 
     obj.MyEvent -= new EventHandler(handler); 
    } 
    static void handler(object sender, EventArgs e) { } 
} 

class MyDynamicObject : DynamicObject { 
    private EventHandler dlg = new EventHandler(delegate { }); 
    public override bool TryGetMember(GetMemberBinder binder, out object result) { 
     result = dlg; 
     return true; 
    } 
    public override bool TrySetMember(SetMemberBinder binder, object value) { 
     dlg = (EventHandler)value; 
     return true; 
    } 
} 
+0

아, TryGetMember 재정의에서 이벤트 핸들러를 가져 오지 않아야하는 이유가 있어야합니다. 이것은 의미가 있습니다. 그러나, 나의 백 엔드는 강등을 위해 자바 스타일 리스너를 사용하는 일련의 신호이다. Type 객체의 배열로 매개 변수 유형에 액세스 할 수 있습니다. 이 문제를 해결하기 위해 리플렉션을 사용하여 각 신호에 대한 대리자를 만들어야한다고 생각합니다. – fettsnoken

-1

당신은 실제로 당신이 제거하는 것을 모르는 DLR이 표시되지 않을 경우 제거 : 난 그냥 작동하는 간단한 뭔가를 게시합니다 정적 이벤트 속성을 사용하는 경우 +=-=을 수행 할 때 동적으로 다음과 같은 작업을 수행합니다.

//d.MyEvent += new EventHandler(this.MyHandler); 
var temp = d.MyEvent; //temp is null 
temp += new EventHandler(this.MyHandler) //temp is now MyHandler 
d.MyEvent = temp; //set it back 

//d.MyEvent -= new EventHandler(this.MyHandler); 
var temp = d.MyEvent; //temp is MyHandler 
temp -= new EventHandler(this.MyHandler) //temp is now null 
d.MyEvent = temp; //set it back 

이벤트 핸들러는 단지 당신이 왼쪽 아무것도 없기 때문에, 마지막에 설정된 속성이 null을해야 제거 할 이벤트 핸들러를했다 그래서 만약 당신이, 모음처럼 생각해야 있도록 MulticastDelegate이다. 믹스에서 더 많은 이벤트가 추가되면 더 명확 해집니다.

//d.MyEvent += new EventHandler(this.MyHandler); 
var temp = d.MyEvent; //temp is null 
temp += new EventHandler(this.MyHandler) //temp is now MyHandler 
d.MyEvent = temp; //set it back 

//d.MyEvent += new EventHandler(this.MyHandler2); 
var temp = d.MyEvent; //temp is MyHandler 
temp += new EventHandler(this.MyHandler2) //temp is now MyHandler,MyHandler2 
d.MyEvent = temp; //set it back 

//d.MyEvent -= new EventHandler(this.MyHandler); 
var temp = d.MyEvent; //temp is MyHandler,MyHandler2 
temp -= new EventHandler(this.MyHandler) //temp is now MyHandler2 
d.MyEvent = temp; //set it back 

당신이 당신의 행동을 포장하고 당신이 당신의 TryGet에 반환 확인 다르게 저장하고 추가를 필요로하고 스토리지 클래스을 제거해야하는 경우

.

public DelegateStoreage<T>{ 

public void Add(T del){ 
    //Do your stuff 
} 
public void Remove(T del){ 
    //Do your stuff 
} 
public static T operator +(DelegateStoreage<T> x, T y) 
    { 
     x.Add(y) 
     return x 
    } 

    public static T operator -(DelegateStoreage<T> x, T y) 
    { 
     x.Remove(y) 
     return y; 
    } 
} 
관련 문제