सी # में कार्रवाई प्रतिनिधि के उपयोग [बंद]


132

मैं सी # में एक्शन डेलिगेट्स के साथ काम कर रहा था ताकि मैं उनके बारे में अधिक सीख सकूं और सोच पाऊं कि वे कहां उपयोगी हो सकते हैं।

क्या किसी ने एक्शन डेलिगेट का उपयोग किया है, और यदि ऐसा है तो क्यों? या आप कुछ उदाहरण दे सकते हैं जहां यह उपयोगी हो सकता है?

जवाबों:


25

MSDN कहता है:

यह प्रतिनिधि सरणी या सूची के प्रत्येक तत्व पर कार्रवाई करने के लिए Array.ForEach विधि और List.ForEach विधि द्वारा उपयोग किया जाता है।

सिवाय इसके कि, आप इसे एक सामान्य प्रतिनिधि के रूप में उपयोग कर सकते हैं जो किसी भी मान को वापस किए बिना 1-3 पैरामीटर लेता है।


मैंने एक्शन के उन मल्टी-पैरामीटर संस्करणों पर कभी गौर नहीं किया। धन्यवाद।
मैकेनिअर

114

यहाँ एक छोटा सा उदाहरण है जो एक्शन प्रतिनिधि की उपयोगिता को दर्शाता है

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Action<String> print = new Action<String>(Program.Print);

        List<String> names = new List<String> { "andrew", "nicole" };

        names.ForEach(print);

        Console.Read();
    }

    static void Print(String s)
    {
        Console.WriteLine(s);
    }
}

ध्यान दें कि फ़ॉर्चेक विधि नामों के संग्रह को पुनरावृत्त करती है और संग्रह के printप्रत्येक सदस्य के विरुद्ध विधि निष्पादित करती है । यह हमारे लिए C # डेवलपर्स का एक बड़ा बदलाव है क्योंकि हम प्रोग्रामिंग की अधिक कार्यात्मक शैली की ओर बढ़ते हैं। (इसके पीछे कंप्यूटर विज्ञान के बारे में अधिक जानकारी के लिए इसे पढ़ें: http://en.wikipedia.org/wiki/Map_(higher-order_function)

अब यदि आप C # 3 का उपयोग कर रहे हैं, तो आप इसे लंबोदर अभिव्यक्ति के साथ थोड़ा सा ऊपर कर सकते हैं:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<String> names = new List<String> { "andrew", "nicole" };

        names.ForEach(s => Console.WriteLine(s));

        Console.Read();
    }
}

68

यदि आप एक स्विच है तो अच्छी तरह से आप कर सकते हैं:

switch(SomeEnum)
{
  case SomeEnum.One:
      DoThings(someUser);
      break;
  case SomeEnum.Two:
      DoSomethingElse(someUser);
      break;
}

और क्रियाओं की शक्ति से आप उस स्विच को शब्दकोश में बदल सकते हैं:

Dictionary<SomeEnum, Action<User>> methodList = 
    new Dictionary<SomeEnum, Action<User>>()

methodList.Add(SomeEnum.One, DoSomething);
methodList.Add(SomeEnum.Two, DoSomethingElse); 

...

methodList[SomeEnum](someUser);

या आप इसे आगे ले जा सकते हैं:

SomeOtherMethod(Action<User> someMethodToUse, User someUser)
{
    someMethodToUse(someUser);
}  

....

var neededMethod = methodList[SomeEnum];
SomeOtherMethod(neededMethod, someUser);

उदाहरण के लिए बस कुछ। बेशक अधिक स्पष्ट उपयोग Linq विस्तार के तरीके होंगे।


महान, मुझे लगता है कि यह एक निर्णय तालिका के रूप में इस्तेमाल किया जा सकता है।
बिस्वनाथ

3
नाइस - यह एक रीफैक्टरिंग पैटर्न है "पॉली कंडीशनल विद पॉलिमॉर्फिज्म"। refactoring.com/catalog/replaceConditionalWithPolymorphism.html
डेविड रॉबिंस

16

आप छोटी ईवेंट हैंडलर के लिए क्रियाओं का उपयोग कर सकते हैं:

btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");

आप उन्हें लंबे लोगों के लिए भी उपयोग कर सकते हैं; btnSubmit.Click + = (प्रेषक, ई) => {MessageBox.Show ("आपने क्लिक किया सेव!")। MessageBox.Show ("आप वास्तव में किया था!"); };
tdgtyugdyugdrugdr

15

मैंने एक बार एक परियोजना में इस तरह के एक्शन प्रतिनिधि का इस्तेमाल किया:

private static Dictionary<Type, Action<Control>> controldefaults = new Dictionary<Type, Action<Control>>() { 
            {typeof(TextBox), c => ((TextBox)c).Clear()},
            {typeof(CheckBox), c => ((CheckBox)c).Checked = false},
            {typeof(ListBox), c => ((ListBox)c).Items.Clear()},
            {typeof(RadioButton), c => ((RadioButton)c).Checked = false},
            {typeof(GroupBox), c => ((GroupBox)c).Controls.ClearControls()},
            {typeof(Panel), c => ((Panel)c).Controls.ClearControls()}
    };

जो कुछ भी करता है, वह एक प्रकार के नियंत्रण के विरुद्ध एक क्रिया (मेथड कॉल) को संग्रहीत करता है ताकि आप सभी नियंत्रणों को एक फॉर्म में वापस वहाँ से हटा सकें।


अच्छा है, परिवर्तन का एक बड़ा सौदा नहीं है, लेकिन कीडेबीटाइप कॉलोनियन नाम की कोई चीज है, हालांकि मुझे लगता है कि यह तानाशाही (प्रकार, वस्तु) के आसपास लपेटता है, हो सकता है।
बिस्वनाथ

13

उदाहरण के लिए कि एक्शन <> का उपयोग कैसे किया जाता है।

Console.WriteLine पर एक हस्ताक्षर है जो व्यंग्य करता है Action<string>

    static void Main(string[] args)
    {
        string[] words = "This is as easy as it looks".Split(' ');

        // Passing WriteLine as the action
        Array.ForEach(words, Console.WriteLine);         
    }

उम्मीद है की यह मदद करेगा


11

मैं इसका उपयोग तब करता हूं जब मैं अवैध क्रॉस थ्रेड कॉल के साथ काम कर रहा हूं उदाहरण के लिए:

DataRow dr = GetRow();
this.Invoke(new Action(() => {
   txtFname.Text = dr["Fname"].ToString();
   txtLname.Text = dr["Lname"].ToString(); 
   txtMI.Text = dr["MI"].ToString();
   txtSSN.Text = dr["SSN"].ToString();
   txtSSN.ButtonsRight["OpenDialog"].Visible = true;
   txtSSN.ButtonsRight["ListSSN"].Visible = true;
   txtSSN.Focus();
}));

मुझे समाधान के लिए रीड कोपसे एसओ उपयोगकर्ता 65358 को क्रेडिट देना चाहिए। उत्तरों के साथ मेरा पूरा प्रश्न SO प्रश्न 2587930 है


3

मैंने इसे एक इवेंट हैंडलर में कॉलबैक के रूप में इस्तेमाल किया। जब मैं घटना को बढ़ाता हूं, तो मैं एक स्ट्रिंग स्ट्रिंग पैरामीटर में एक विधि से गुजरता हूं। यह इस तरह घटना को बढ़ाता है:

SpecialRequest(this,
    new BalieEventArgs 
    { 
            Message = "A Message", 
            Action = UpdateMethod, 
            Data = someDataObject 
    });

प्रक्रिया:

   public void UpdateMethod(string SpecialCode){ }

इस घटना की कक्षा घोषणा है:

public class MyEventArgs : EventArgs
    {
        public string Message;
        public object Data;
        public Action<String> Action;
    }

इस तरह मैं डेटा को अपडेट करने के लिए कुछ पैरामीटर के साथ इवेंट हैंडलर से पारित विधि को कॉल कर सकता हूं। मैं इसका उपयोग उपयोगकर्ता से कुछ जानकारी का अनुरोध करने के लिए करता हूं।


हाय Sorskoot, क्या आप विस्तार कर सकते हैं कि कैसे UpdateMethod, MyEventArgs और नए BalieEventArgs एक साथ खेल रहे हैं। क्या स्ट्रिंग संदेश UpdateMethod में अपडेट किया गया है: UpdateMethod ("एक संदेश")? कौन सी विधि "someDataObject" ऑब्जेक्ट का उपयोग करती है? अग्रिम धन्यवाद
सर्फ करें

2

हम परीक्षणों में बहुत सारे एक्शन प्रतिनिधि कार्यक्षमता का उपयोग करते हैं। जब हमें कुछ डिफ़ॉल्ट ऑब्जेक्ट बनाने की आवश्यकता होती है और बाद में इसे संशोधित करने की आवश्यकता होती है। मैंने बहुत कम उदाहरण दिए। डिफ़ॉल्ट व्यक्ति (जॉन डो) ऑब्जेक्ट बनाने के लिए हम BuildPerson()फ़ंक्शन का उपयोग करते हैं। बाद में हम जेन डो को भी जोड़ते हैं, लेकिन हम उसकी जन्मतिथि और नाम और ऊंचाई को संशोधित करते हैं।

public class Program
{
        public static void Main(string[] args)
        {
            var person1 = BuildPerson();

            Console.WriteLine(person1.Firstname);
            Console.WriteLine(person1.Lastname);
            Console.WriteLine(person1.BirthDate);
            Console.WriteLine(person1.Height);

            var person2 = BuildPerson(p =>
            {
                p.Firstname = "Jane";
                p.BirthDate = DateTime.Today;
                p.Height = 1.76;
            });

            Console.WriteLine(person2.Firstname);
            Console.WriteLine(person2.Lastname);
            Console.WriteLine(person2.BirthDate);
            Console.WriteLine(person2.Height);

            Console.Read();
        }

        public static Person BuildPerson(Action<Person> overrideAction = null)
        {
            var person = new Person()
            {
                Firstname = "John",
                Lastname = "Doe",
                BirthDate = new DateTime(2012, 2, 2)
            };

            if (overrideAction != null)
                overrideAction(person);

            return person;
        }
    }

    public class Person
    {
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public DateTime BirthDate { get; set; }
        public double Height { get; set; }
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.