मैं भी यह करने के लिए करना चाहता था, और मैं एक बहुत अच्छा तरीका है कि सम्राट XLII विचार की तरह कुछ करता है के साथ आए हैं। हालांकि अभिव्यक्ति पेड़ों का उपयोग नहीं करता है, जैसा कि बताया गया है कि यह अभिव्यक्ति पेड़ के रूप में नहीं किया जा सकता है +=
या -=
के उपयोग की अनुमति नहीं देता है।
हम हालांकि एक साफ चाल का उपयोग कर सकते हैं जहां हम .NET Remoting Proxy (या किसी भी अन्य प्रॉक्सी जैसे कि लिनफू या कैसल डीपी) का उपयोग करते हैं ताकि एक बहुत ही कम जीवित प्रॉक्सी ऑब्जेक्ट पर हैंडलर जोड़ें/निकालें। इस प्रॉक्सी ऑब्जेक्ट की भूमिका केवल उस पर कुछ विधि कहा जाता है, और इसकी विधि को अवरुद्ध करने की अनुमति देने के लिए, जिस बिंदु पर हम ईवेंट का नाम ढूंढ सकते हैं।
यह अजीब लगता है, लेकिन यहाँ कोड (जो वैसे ही काम करता है अगर आप एक 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>
प्रतिनिधि के लिए प्रॉक्सी वस्तु पारित करने के लिए है।
कहाँ हम निम्नलिखित CustomProxy<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;
}
}
पर +=
और -=
करने के लिए कॉल को बीच में रोक दिया है और फिर हम सब अब सिर्फ़ रूप
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