इंटरफ़ेस C # में एक प्रतिनिधि कैसे जोड़ें


91

मुझे अपनी कक्षा में कुछ प्रतिनिधियों की आवश्यकता है।

मैं इन प्रतिनिधियों को सेट करने के लिए मुझे "याद दिलाने" के लिए इंटरफ़ेस का उपयोग करना चाहूंगा।

कैसे?

मेरी कक्षा इस तरह दिखती है:

public class ClsPictures : myInterface
{
    // Implementing the IProcess interface
    public event UpdateStatusEventHandler UpdateStatusText;
    public delegate void UpdateStatusEventHandler(string Status);

    public event StartedEventHandler Started;
    public delegate void StartedEventHandler();
}

मुझे उन प्रतिनिधियों को बाध्य करने के लिए एक इंटरफ़ेस की आवश्यकता है:

public interface myInterface
{
   // ?????
}

जवाबों:


142

वे प्रतिनिधि प्रकार की घोषणा कर रहे हैं । वे एक इंटरफेस में नहीं हैं। उन प्रतिनिधि प्रकारों का उपयोग करने वाली घटनाएं हालांकि इंटरफ़ेस में होना ठीक हैं:

public delegate void UpdateStatusEventHandler(string status);
public delegate void StartedEventHandler();

public interface IMyInterface
{       
    event UpdateStatusEventHandler StatusUpdated;    
    event StartedEventHandler Started;
}

कार्यान्वयन प्रतिनिधि के प्रकार को नहीं करेगा (और नहीं करना चाहिए), किसी भी अन्य की तुलना में किसी इंटरफ़ेस में उपयोग किए गए किसी अन्य प्रकार को फिर से निर्दिष्ट नहीं करेगा।


यह सिर्फ मेरे लिए काम नहीं कर रहा है। मैं सकारात्मक हूं मैंने इस तरह से सब कुछ किया है, और फिर भी, मेरे इंटरफ़ेस के भीतर मेरे हैंडलर को मान्यता नहीं मिल रही है। इंटरफ़ेस को लागू करने वाला मेरा वर्ग शिकायत कर रहा है कि वर्ग इंटरफ़ेस वापसी प्रकार के System.EventHandler से मेल नहीं खाता है।
चकी

1
@Chucky: लगता है जैसे आपको एक छोटा लेकिन पूर्ण उदाहरण के साथ एक नया सवाल पूछना चाहिए जिससे समस्या को ख़त्म किया जा सके। मैंने जो उत्तर दिया है वह वास्तव में काम करता है
जॉन स्कीट

4
मुझे महसूस नहीं हुआ कि प्रतिनिधियों के पास कक्षाओं के समान पहुंच का स्तर है। मैंने हमेशा सोचा था कि उन्हें एक वर्ग के भीतर समझाया जाना चाहिए।
पुरुषार्थ

7
@Purusartha: यह एक्सेसिबिलिटी नहीं है - यह केवल प्रतिनिधियों के प्रकार (कक्षाएं, वास्तव में) के रूप में सिर्फ इंटरफेस आदि के रूप में है
जॉन स्कीट

29

.NET 3.5 के बाद से आप अपने प्रकार को घोषित करने की आवश्यकता के बिना भी System.Action प्रतिनिधियों का उपयोग कर सकते हैं।

यह निम्नलिखित इंटरफ़ेस में परिणाम देगा:

public interface myInterface
{       
   // Implementing the IProcess interface
   event Action<String> UpdateStatusText;

   event Action Started;
}

+1। मुझे पारंपरिक प्रतिनिधि प्रकारों की तुलना में एक्शन / फंक कहीं अधिक सुरुचिपूर्ण (और पठनीय) लगता है और आप उन्हें अपने इंटरफ़ेस में परिभाषित कर सकते हैं।
चर्नोला

2
यह उत्तर प्रश्न (myInterface को लागू करने का तरीका) को संबोधित नहीं करता है।
lharper71

10

बस प्रतिनिधि को एक संपत्ति के रूप में उजागर करें

public delegate void UpdateStatusEventHandler(string status);
public delegate void StartedEventHandler();

public interface IMyInterface
{       
    UpdateStatusEventHandler StatusUpdated {get; set;}    
    StartedEventHandler Started {get; set;}
}

7

जॉन स्कीट का जवाब सही है, मैं सिर्फ एक नोट जोड़ना चाहता हूं।

इंटरफेस आपको "याद दिलाने" के लिए नहीं हैं कि आपको क्या करना है, या अपनी कक्षाओं में क्या शामिल करना है। इंटरफेस एब्सट्रैक्शन के साधन हैं, जिसका उपयोग ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग और डिज़ाइन विधियों में किया जाता है। हो सकता है कि आपको किसी इंटरफ़ेस घोषणा की आवश्यकता न हो, जब तक कि आप अपने प्रोग्राम (एब्स्ट्रक्शन) में इंटरफ़ेस के रूप में कुछ ठोस वर्ग उदाहरण नहीं देखना चाहते।

यदि आप अपनी परियोजना में कुछ कोडिंग मानकों को लागू करना चाहते हैं, तो आप कोड विश्लेषण टूल (जैसे विजुअल स्टूडियो) का उपयोग करके कोशिश कर सकते हैं - वे एक्सटेंशन की अनुमति देते हैं, जिसे आप खुद कोड विश्लेषण नियमों को जोड़ने के लिए शामिल कर सकते हैं।

कोड विश्लेषण का उपयोग करना, यदि आप प्रतिनिधियों को जोड़ने के लिए "भूल जाते हैं" (हालांकि मुझे इसे भूलने की बात नहीं दिखती है, जैसे कि प्रतिनिधि का उपयोग नहीं किया गया है, इसकी आवश्यकता नहीं है) आपको एक चेतावनी / त्रुटि मिलेगी।


1
आप सही हो सकते हैं, लेकिन कुछ ऐसे समय होते हैं जब आप कुछ ऐसी धारणाएँ बनाते हैं कि अच्छे दस्तावेज़ के साथ भी कुछ समय बाद याद रखना मुश्किल होता है। मैं अपने कोड का पुन: उपयोग करने की कोशिश करता हूं, लेकिन कभी-कभी मुझे यह याद नहीं रहता है कि यह क्या है और यह क्या नहीं है (जब यह प्रतिनिधियों की बात आती है - यह मेरे लिए बड़ी तस्वीर को देखना मुश्किल है ...)
आसफ

1

आपकी एक टिप्पणी ने इवेंट हैंडलर के रिटर्न प्रकार को संदर्भित किया। क्या आप हैंडलर के प्रकार, या घटना से वापस आने वाले डेटा से अधिक चिंतित हैं? यदि यह बाद की बात है, तो इससे मदद मिल सकती है। यदि नहीं, तो यह समाधान पर्याप्त नहीं होगा, लेकिन आप जो खोज रहे हैं, उसके करीब पहुंचने में आपकी मदद कर सकता है।

आपको बस अपने ईवेंट हैंडलर को इंटरफ़ेस और आपके कार्यान्वयन दोनों में जेनेरिक ईवेंट हैंडलर के रूप में घोषित करना है और आप रिटर्न परिणामों को अनुकूलित कर सकते हैं।

आपका शंकराचार्य वर्ग इस तरह दिखेगा:

public class ClsPictures : myInterface
{
    // Implementing the IProcess interface
    public event EventHandler<UpdateStatusEventArgs> UpdateStatusText;
    //no need for this anymore: public delegate void UpdateStatusEventHandler(string Status);

    public event EventHandler<StartedEventArgs> Started;
    //no need for this anymore: public delegate void StartedEventHandler();
}

आपका इंटरफ़ेस इस तरह दिखेगा:

public interface myInterface
{
   event EventHandler<StartedEventArgs> Started;
   event EventHandler<UpdateStatusEventArgs> UpdateStatusText;
}

अब जब कि घटना आर्ग आपके प्रकारों को वापस कर रही है, तो आप उन्हें अपने द्वारा परिभाषित किसी भी हैंडलर में हुक कर सकते हैं।

संदर्भ के लिए: https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx


0

आपके व्युत्पन्न वर्ग के भीतर विरासत में मिला इंटरफ़ेस आपको इसमें बताए गए सामान को परिभाषित और लिंक करने के लिए याद दिलाएगा।

लेकिन आप इसे स्पष्ट रूप से उपयोग करना चाहते हैं और फिर भी आपको इसे किसी वस्तु से जोड़ना होगा।

उदाहरण के लिए नियंत्रण पैटर्न के व्युत्क्रम का उपयोग करना:

class Form1 : Form, IForm {
   public Form1() {
     Controls.Add(new Foo(this));
   }

   // Required to be defined here.
   void IForm.Button_OnClick(object sender, EventArgs e) {
     ...
     // Cast qualifier expression to 'IForm' assuming you added a property for StatusBar.
     //((IForm) this).StatusBar.Text = $"Button clicked: ({e.RowIndex}, {e.SubItem}, {e.Model})";
   }
 }

आप कुछ इस तरह की कोशिश कर सकते हैं।

interface IForm {
  void Button_OnClick(object sender, EventArgs e);
}


class Foo : UserControl {
  private Button btn = new Button();

  public Foo(IForm ctx) {
     btn.Name = "MyButton";
     btn.ButtonClick += ctx.Button_OnClick;
     Controls.Add(btn);
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.