가 나도이 일을 원했고, 나는 황제 XLII 아이디어 같은 것을 수행하는 정말 멋진 방법으로 올라와있다. 표현식 트리에서는 +=
또는 -=
을 사용할 수 없기 때문에 표현식 트리를 사용하지 않습니다.
그러나 .NET Remoting Proxy (또는 LinFu 또는 Castle DP와 같은 다른 프록시)를 사용하여 매우 짧은 수명의 프록시 개체에서 Add/Remove 처리기에 대한 호출을 차단할 수 있습니다. 이 프록시 객체의 역할은 단순히 메소드를 호출하고 메소드 호출을 가로 채기 위해 이벤트의 이름을 찾을 수있게하는 것입니다.
이 여기에 이상한 소리를하지만
우리는 다음과 같은 인터페이스와 클래스가 가정 (당신이 프록시 객체에 대한 MarshalByRefObject
또는 인터페이스가있는 경우 방식으로 만 작동) 코드입니다
public interface ISomeClassWithEvent {
event EventHandler<EventArgs> Changed;
}
public class SomeClassWithEvent : ISomeClassWithEvent {
public event EventHandler<EventArgs> Changed;
protected virtual void OnChanged(EventArgs e) {
if (Changed != null)
Changed(this, e);
}
}
그런 다음 Action<T>
대리자가 T
의 일부 인스턴스를 전달할 것으로 예상되는 매우 간단한 클래스를 만들 수 있습니다.
여기
public class EventWatcher<T> {
public void WatchEvent(Action<T> eventToWatch) {
CustomProxy<T> proxy = new CustomProxy<T>(InvocationType.Event);
T tester = (T) proxy.GetTransparentProxy();
eventToWatch(tester);
Console.WriteLine(string.Format("Event to watch = {0}", proxy.Invocations.First()));
}
}
트릭 제공된 Action<T>
위임하는 프록시 객체를 전달할 수있는 코드이다.우리는 프록시 객체
public enum InvocationType { Event }
public class CustomProxy<T> : RealProxy {
private List<string> invocations = new List<string>();
private InvocationType invocationType;
public CustomProxy(InvocationType invocationType) : base(typeof(T)) {
this.invocations = new List<string>();
this.invocationType = invocationType;
}
public List<string> Invocations {
get {
return invocations;
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
[DebuggerStepThrough]
public override IMessage Invoke(IMessage msg) {
String methodName = (String) msg.Properties["__MethodName"];
Type[] parameterTypes = (Type[]) msg.Properties["__MethodSignature"];
MethodBase method = typeof(T).GetMethod(methodName, parameterTypes);
switch (invocationType) {
case InvocationType.Event:
invocations.Add(ReplaceAddRemovePrefixes(method.Name));
break;
// You could deal with other cases here if needed
}
IMethodCallMessage message = msg as IMethodCallMessage;
Object response = null;
ReturnMessage responseMessage = new ReturnMessage(response, null, 0, null, message);
return responseMessage;
}
private string ReplaceAddRemovePrefixes(string method) {
if (method.Contains("add_"))
return method.Replace("add_","");
if (method.Contains("remove_"))
return method.Replace("remove_","");
return method;
}
}
을에 +=
및 -=
에 대한 호출을 차단 다음 CustomProxy<T>
코드를 가지고 그리고 남아있는 것을 우리 모두가
class Program {
static void Main(string[] args) {
EventWatcher<ISomeClassWithEvent> eventWatcher = new EventWatcher<ISomeClassWithEvent>();
eventWatcher.WatchEvent(x => x.Changed += null);
eventWatcher.WatchEvent(x => x.Changed -= null);
Console.ReadLine();
}
}
을 다음과 같이 사용하는 것입니다
이렇게하면 다음 출력이 표시됩니다.
Event to watch = Changed
Event to watch = Changed