क्या .NET में एक अंतर्निहित EventArgs <T> है?


84

मैं एक घटना के लिए एक सामान्य ईवेंटआर्ग्स क्लास बनाने के लिए तैयार हो रहा हूं जो एक ही तर्क देता है:

public class EventArg<T> : EventArgs
{
    // Property variable
    private readonly T p_EventData;

    // Constructor
    public EventArg(T data)
    {
        p_EventData = data;
    }

    // Property for EventArgs argument
    public T Data
    {
        get { return p_EventData; }
    }
}

इससे पहले कि मैं ऐसा करूं, क्या C # में भाषा के लिए समान सुविधा है? मुझे ऐसा कुछ याद आ रहा है, जब C # 2.0 बाहर आया था, लेकिन अब मुझे यह नहीं मिल रहा है।

या इसे दूसरे तरीके से रखने के लिए, क्या मुझे अपना जेनेरिक EventArgs क्लास बनाना होगा, या C # प्रदान करना है? आपकी सहायता के लिए धन्यवाद।


9
आपने देखा होगाEventhandler<T>
हेनक होल्टरमैन

1
आपने EventArgs<T>CAB / SCSF- आधारित कोड में देखा होगा। यह CAB / SCSF अनुप्रयोगों में काफी सामान्य है। हालांकि यह रूपरेखा का हिस्सा नहीं है, फिर भी EventArgs <T> कार्यान्वयन है।
शॉन विल्सन

जवाबों:


66

नहीं। आप शायद सोच रहे थे EventHandler<T>, जो आपको किसी विशेष प्रकार के EventArgs के लिए प्रतिनिधि को परिभाषित करने की अनुमति देता है।

मैं व्यक्तिगत EventArgs<T>रूप से महसूस नहीं करता हूं कि यह एक फिट के रूप में काफी अच्छा है, हालांकि। घटना के आर्ग में "पेलोड" के रूप में उपयोग की जाने वाली जानकारी, मेरी राय में, यह उपयोग करने के लिए एक कस्टम वर्ग और अपेक्षित गुण स्पष्ट होना चाहिए। एक सामान्य वर्ग का उपयोग करने से आप सार्थक नामों को रखने में सक्षम होंगे। ("डेटा" क्या दर्शाता है?)


50
डेटा-केंद्रित, MPI- जैसे एप्लिकेशन में डेटा प्रोसेसिंग के लिए एक EventArgs <T> को देखना काफी आम है ताकि डेवलपर्स इन-बिल्ट, टाइप-सेफ सब्सक्रिप्शन / रजिस्ट्रेशन सिस्टम (.NET इवेंट्स और डेलिगेट्स) का लाभ उठा सकें। के रूप में यह सिर्फ डेटा परिवहन के लिए EventArgs उपवर्ग बनाने के लिए बिल्कुल कोई मतलब नहीं है। यदि आपका इरादा डेटा ट्रांसपोर्ट करने का है, तो निश्चित रूप से EventArgs <T> को परिभाषित करने के लिए अधिक समझ में आता है, आप डेटा के परिवहन के संबंध में असतत उपयोगों के लिए उप-वर्ग कर सकते हैं। TL: DR इस उत्तर का पहला भाग तथ्यपूर्ण और सटीक है, दूसरा भाग व्यक्तिपरक / राय है।
शॉन विल्सन

1
मुझे लगता है कि आप सही हैं ... मुझे यहाँ मिले आलस का विरोध करें। यह तब होता है जब आलसी डेवलपर्स टपल <,> का उपयोग करते हैं। भयानक सामान।

एक अच्छी बात है, लेकिन यह अनिवार्य रूप से वही काम करेगा जो माइक्रोसॉफ्ट ने तब किया था जब उन्होंने टैग की संपत्ति को नियंत्रण कक्षाओं में जोड़ा था। बेशक, सिर्फ coz 'एमएस किया, यह सही नहीं है।
केन रिचर्ड्स

1
मैं पहले टिप्पणीकार से सहमत हूं, इस उत्तर के पूरे उत्तरार्ध में एक व्यक्तिपरक राय / कोड-धर्म है जो रचनात्मक नहीं था। :(
BrainSlugs83

5
कैसे करता है eventhandler <ग्राहक> या eventhandler <आदेश> से किसी भी कम जानकारी देने के CustomerEventHandler या OrderEventHandler ?
क्वार्कली

33

मुझे यह कहना चाहिए कि मैं यहाँ सभी 'शुद्धतावादियों' को नहीं समझता। यानी यदि आपके पास पहले से ही एक बैग क्लास परिभाषित है - जिसमें सभी बारीकियां, गुण आदि हैं - तो हैक एक अतिरिक्त अनावश्यक वर्ग क्यों बना सकता है, जो ईवेंट / आर्ग्स तंत्र, हस्ताक्षर शैली का अनुसरण करने में सक्षम हो सकता है? बात यह है कि - वह सब कुछ जो .NET में नहीं है - या उस मामले के लिए 'से' गायब है - 'अच्छा' है - MS वर्षों से खुद को 'सही' कर रहा है ... मैं कहूंगा कि बस जाओ और एक बनाएं - जैसे मैंने किया था - क्योंकि मुझे इसकी ज़रूरत थी - और मुझे बहुत समय बचाया,


3
इस मामले में, 'प्यूरिस्ट्स' बिंदु का इरादा यथासंभव स्पष्ट करना है। एक उत्पादन ऐप में, मेरे पास इन EventArgs वर्गों के दर्जनों हैं। अब से एक साल बाद, यह समझना आसान होगा कि मैंने रीड की सलाह का पालन किया और एक कस्टम EventArgs क्लास बनाया तो मैंने क्या किया।
डेविड वीमेन

9
किसी को भी लेबल करने का मतलब नहीं था :) बिंदु घटना में 'सामान्य' में है - यदि आपको बस एक दर्जन विभिन्न घटनाओं की आवश्यकता है, तो ठीक है। लेकिन अगर आप पहले से T की प्रकृति को नहीं जानते हैं - जो केवल रनटाइम में जाना जाता है - ठीक है, आपको एक सामान्य घटना की आवश्यकता है। इसलिए, यदि आपके पास कोई ऐसा ऐप है जो w / जेनेरिक से निपटने वाला एक अच्छा हिस्सा है, तो एक अनजान # प्रकार का, अज्ञात - तो आपको जेनेरिक घटनाओं की भी आवश्यकता है। या इसका मतलब है कि हर समस्या के लिए कोई क्लीन-कट समाधान नहीं है, अंगूठे का नियम सिर्फ अंगूठे का एक नियम है - और यही मेरा मतलब है कि शुद्धतावादियों का मतलब है, प्रत्येक समाधान अलग है, आपको चीजों, पेशेवरों और विपक्षों का वजन करने की आवश्यकता है
NSGaga-ज्यादातर- निष्क्रिय

2
डिज़ाइन काला और सफेद नहीं है, इसलिए मैं यहाँ NSGaga से सहमत हूँ। कभी-कभी, "त्वरित और गंदा" उपयुक्त है। अधिकांश उपयोग के मामलों के लिए भाषा को सुविधा संपन्न होना चाहिए। यह तय करने के लिए डेवलपर पर निर्भर होना चाहिए कि क्या उपयुक्त है। पिछली बार MS ने भाषा को सीमित करके "अच्छे" डिजाइन को बल देने की कोशिश की थी WPF जब उन्होंने .NET एपीआई को गंभीर रूप से बाधा देकर XAML के उपयोग को मजबूर करने की कोशिश की, और यह भयानक था।
Robear

9

यह मौजूद है। कम से कम, यह अब करता है।

आप DataEventArgs<TData>कुछ अलग Microsoft असेंबली / नेमस्पेस में पा सकते हैं , उदाहरण के लिए Microsoft.Practices.Prism.Events । हालाँकि ये ऐसे नामस्थान हैं जिन्हें आप अपनी परियोजना में शामिल करने के लिए स्वाभाविक नहीं मान सकते हैं ताकि आप अपने स्वयं के कार्यान्वयन का उपयोग कर सकें।


मैं कब और क्यों इस तरह के एक सामान्य घटनाआग्र्स वर्ग का उपयोग करने के बारे में सिफारिशों और विचारों को खोजने की कोशिश कर रहा हूं। इन्हें भी देखें: stackoverflow.com/questions/15766219/…
Ulf stedStstedt

जेनेरिक EventArgs का उपयोग करते समय सावधान रहने के कुछ पहलू यहां दिए गए हैं: stackoverflow.com/questions/129453/…
Ulf stedstedstedt

7

मामले में आप प्रिज्म का उपयोग नहीं करना चुनते हैं , लेकिन फिर भी एक सामान्य ईवेंटआर्ग्स दृष्टिकोण की कोशिश करना चाहते हैं ।

public class GenericEventArgs<T> : EventArgs
{
    public T EventData { get; private set; }

    public GenericEventArgs(T EventData)
    {
        this.EventData = EventData;
    }
}

// ObjAdded घटना घोषित करने के लिए निम्न नमूना कोड का उपयोग करें

public event EventHandler<GenericEventArgs<TargetObjType>> ObjAdded;

// ObjAdded घटना को बढ़ाने के लिए निम्न नमूना कोड का उपयोग करें

private void OnObjAdded(TargetObjType TargetObj)
{
    if (ObjAdded!= null)
    {
        ObjAdded.Invoke(this, new GenericEventArgs<TargetObjType>(TargetObj));
    }
}

// और finnaly आप अपने ObjAdded घटना की सदस्यता ले सकते हैं

SubscriberObj.ObjAdded +=  (object sender, GenericEventArgs<TargetObjType> e) =>
{
    // Here you can explore your e.EventData properties
};

3

यहाँ कोई सृजन-संधि नहीं है। यदि आप Microsoft EventHandler पैटर्न का अनुसरण करते हैं, तो आप अपने सुझाए गए EventArgs को लागू करते हैं, जैसे आपने सुझाया था public class MyStringChangedEventArgs : EventArgs { public string OldValue { get; set; } }:।

कैसे - अगर आपकी टीम स्टाइल गाइड एक सरलीकरण स्वीकार करती है - आपकी परियोजना इस तरह से एक हल्के घटनाओं का उपयोग कर सकती है:

public event Action<object, string> MyStringChanged;

उपयोग:

// How to rise
private void OnMyStringChanged(string e)
{
    Action<object, string> handler = MyStringChanged;    // thread safeness
    if (handler != null)
    {
        handler(this, e);
    }
}

// How to handle
myObject.MyStringChanged += (sender, e) => Console.WriteLine(e);

आमतौर पर पीओसी परियोजनाएं बाद के दृष्टिकोण का उपयोग करती हैं। हालांकि, पेशेवर आवेदकों में, FX पुलिस औचित्य # CA1009 से अवगत रहें: https://msdn.microsoft.com/en-us/library/ms182133.aspx


1

एक सामान्य प्रकार के साथ समस्या यह है कि भले ही DerivedType BaseType से विरासत में मिला हो, EventArgs (DerTType) EventArgs (बेसटाइप) से विरासत में नहीं मिलेगा। EventArgs (BaseType) का उपयोग करना इस प्रकार प्रकार के व्युत्पन्न संस्करण का उपयोग करने से बाद में रोक देगा।


2
यह तो झूठा है। कृपया "Covariance and Contravariance in Generics - Microsoft.com" देखें msdn.microsoft.com/en-us/library/dd799517.aspx
Shaun Wilson

1
@ शॉनविलसन: कौन सा पहलू गलत है? एक सहसंयोजक इंटरफ़ेस को परिभाषित कर सकता है IEventArgs, लेकिन सामान्य प्रकार के मापदंडों के संबंध में केवल कक्षाएं जो सामान्य हो सकती हैं, वे प्रतिनिधि हैं जिन्हें खिलाया नहीं जाएगा Delegate.Combine। ऐसे डेलीगेट्स जिनका उपयोग Delegate.Combineसहसंयोजक नहीं किया जाना चाहिए, क्योंकि कोई उदाहरण के Action<DerivedType>एक क्षेत्र में उदाहरण के लिए स्टोर कर सकता है Action<BaseType>, लेकिन बाद में इसके Combineउदाहरण के साथ प्रयास Action<BaseType>विफल हो जाएगा।
21

-4

इसका कारण यह नहीं है कि क्या हो रहा है क्योंकि आप इसे लागू कर रहे हैं, और फिर जब आप T को भरने के लिए जाते हैं तो आपको एक वर्ग बनाना चाहिए जिसमें दृढ़ता से टाइप किए गए अस्पष्ट गुण होते हैं जो आपके ईवेंट arg के लिए डेटा बैग के रूप में कार्य करता है, लेकिन आधे रास्ते को लागू करने के बाद आपको पता चलता है कि ऐसा कोई कारण नहीं है कि आप EventArgs से उस वर्ग को वारिस न बनाएं और इसे अच्छा कहें।

जब तक आप सिर्फ अपने डेटा बैग के लिए एक स्ट्रिंग या कुछ इसी तरह की बुनियादी चाहते हैं, जिस स्थिति में शायद .NET में EventArgs कक्षाएं मानक हैं जो कि आपके द्वारा प्राप्त किए जाने वाले सरल उद्देश्य को पूरा करने के लिए हैं।


-1। मेरे पास अब यह स्थिति है, और मेरा पेलोड एक अपरिवर्तनीय वस्तु होगी जो एक बस से आने वाला "संदेश" है और अन्य स्थानों पर भी isu sed है। कस्टम EventArgs .... यहाँ एक निरर्थक वर्ग बनाता है। असामान्य, लेकिन आवेदन ऐसा है।
टॉमटॉम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.