Func <string, string> और प्रतिनिधि में क्या अंतर है?


81

मैं प्रतिनिधियों को दो रूपों में देखता हूं:

A. Func<string, string> convertMethod = lambda 

B. public delegate string convertMethod(string value);

मैं वास्तव में इन दोनों के बीच के अंतर के बारे में अनिश्चित हूं। क्या वे दोनों प्रतिनिधि हैं? मेरा मानना ​​है कि पहले एक मेमने का इस्तेमाल करेगा और दूसरे के पास वास्तव में काम करने के लिए एक तरीका होगा। मुझे भी भ्रम हो सकता है।


जवाबों:


74

सबसे पहले, आपके दो उदाहरण दो पूरी तरह से अलग चीजें कर रहे हैं। पहला एक सामान्य प्रतिनिधि चर घोषित कर रहा है और इसे एक मान दे रहा है, दूसरा केवल एक delegateप्रकार को परिभाषित कर रहा है । आपका उदाहरण, और अधिक पूरी तरह से, होगा:

public static class Program
{
    // you can define your own delegate for a nice meaningful name, but the
    // generic delegates (Func, Action, Predicate) are all defined already
    public delegate string ConvertedMethod(string value);

    public static void Main()
    {
        // both work fine for taking methods, lambdas, etc.
        Func<string, string> convertedMethod = s => s + ", Hello!";
        ConvertedMethod convertedMethod2 = s => s + ", Hello!";
    }
}

लेकिन बात करने के लिए और अधिक, दोनों Func<string,string>और delegate string convertMethod(string)एक ही विधि परिभाषाओं कि क्या वे तरीकों, गुमनाम तरीकों, या लैम्ब्डा भाव होना पकड़े करने में सक्षम हो जाएगा।

जिसके लिए आपको उपयोग करना चाहिए, स्थिति पर निर्भर करता है। यदि आप चाहते हैं कि आपके प्रतिनिधि को अधिक परिभाषित किया जाए कि वह क्या लेता है और वापस लौटता है, तो सामान्य प्रतिनिधि परिपूर्ण हैं। यदि आप चाहते हैं कि प्रतिनिधि का कुछ विशेष नाम हो, जो उस प्रतिनिधि को क्या करना चाहिए (परिभाषा से परे Action, सरल होना चाहिए) की अधिक परिभाषा देता है , Predicateतो अपना स्वयं का प्रतिनिधि बनाना हमेशा एक विकल्प होता है।


1
एक और भी स्पष्ट उदाहरण होगा Func<int, string>, जो दर्शाता है कि फॉर्म है Func<arg1, result>
सिल्वल्ली

6
मुझे लगता है कि यह ध्यान देने योग्य है कि फंक और एक्शन प्रतिनिधि हैं। जब आप इसे जानते हैं तो यह स्पष्ट प्रतीत होता है, लेकिन फंक के हस्ताक्षर को देखने से पहले मैं इस तथ्य के बारे में पता लगा रहा था। इसलिए जब आप कहते हैं: "सबसे पहले, आपके दो उदाहरण दो बिल्कुल अलग चीजें कर रहे हैं।" आप यह भी कह सकते हैं: "फ़ंक एक प्रतिनिधि है"।
फॉक

12

आपके पास जो कोड सैंपल है वह चीजों को थोड़ा भ्रमित कर रहा है इसलिए मुझे इसे आज़माने और साफ़ करने दें। निम्नलिखित 2 आइटम प्रतिनिधि घोषणाएँ हैं। ये स्पॉट करना आसान है क्योंकि इनमें हमेशा delegateकीवर्ड होंगे

public delegate TReturn Func<TArg, TReturn>(Targ value);
public delegate string convertMethod(string value);

कोड की यह पंक्ति एक स्थानीय को एक मान दे रही है जो एक प्रतिनिधि को टाइप किया गया है

Func<string, string> local = lambda;

हालांकि उपरोक्त कोड केवल लैंबडा का उपयोग करने तक सीमित नहीं है। मान संगत विधि समूह या अन्य प्रतिनिधि मान भी हो सकता है।

ध्यान देने के लिए एक अन्य आइटम यह है कि भले ही Func<string, string>और convertMethodदोनों समान हस्ताक्षर वाले प्रतिनिधि हों लेकिन उनके मूल्य एक दूसरे के लिए परिवर्तनीय नहीं हैं । उदाहरण के लिए निम्नलिखित अवैध है

Func<string, string> local1 = ...;
convertMethod local2 = local1; // Error!!!

8

से MSDN ,

2.0 से पहले C # के संस्करणों में, एक प्रतिनिधि को घोषित करने का एकमात्र तरीका नामित विधियों का उपयोग करना था। C # 2.0 ने अनाम विधियों की शुरुआत की और C # 3.0 में और बाद में, लैम्बडा एक्सप्रेशन इनलाइन कोड लिखने के पसंदीदा तरीके के रूप में अनाम विधियों को सुपरसेड किया।

तथा

एक मामला है जिसमें एक अनाम विधि लैम्बडा के भावों में नहीं पाई गई कार्यक्षमता प्रदान करती है। अनाम विधियाँ आपको पैरामीटर सूची से बाहर निकलने में सक्षम बनाती हैं। इसका मतलब है कि एक अनाम विधि को विभिन्न प्रकार के हस्ताक्षर के साथ प्रतिनिधियों में परिवर्तित किया जा सकता है।

आप इस SO उत्तर में प्रतिनिधि कीवर्ड बनाम लैम्ब्डा अभिव्यक्ति पर भी रुचि ले सकते हैं ।

इसके अतिरिक्त, MSDN के पास लैम्ब्डा एक्सप्रेशन पर एक अच्छा लेख है :

delegate int del(int i);
static void Main(string[] args)
{
    del myDelegate = x => x * x;
    int j = myDelegate(5); //j = 25
}

पिछले उदाहरण में, ध्यान दें कि प्रतिनिधि हस्ताक्षर में एक इंट-टाइप टाइप इनपुट इनपुट पैरामीटर है, और एक इंट रिटर्न करता है। लैम्ब्डा अभिव्यक्ति को उस प्रकार के प्रतिनिधि के रूप में परिवर्तित किया जा सकता है क्योंकि इसमें एक इनपुट पैरामीटर (x) और एक रिटर्न वैल्यू है जो कंपाइलर अंतर्निहित रूप से इंट में बदल सकता है। (निम्न प्रकारों में अधिक प्रकार के संदर्भ में चर्चा की जाती है।) जब प्रतिनिधि को 5 के इनपुट पैरामीटर का उपयोग करके आमंत्रित किया जाता है, तो यह 25 का परिणाम देता है।


आप लंबोदर से मापदंडों को भी छोड़ सकते हैं। () => कंसोल। वाइटलाइन ("पैरामीटर कम लैम्ब्डा")
डॉ। देव

कार्रवाई परीक्षण = () => कंसोल। वाइटलाइन ("पैरामीटर कम लैम्ब्डा"); test.Inoke ();
डॉ। देव

5

एक प्रतिनिधि के एक उदाहरण को इनिशियलाइज़ करता है (जिसे तुरंत कहा जा सकता है)। यह फंक <string, string> प्रकार का एक वैरिएबल है।

बी एक प्रतिनिधि (इसकी हस्ताक्षर) की परिभाषा को निर्दिष्ट करता है। इसका उपयोग बाद में टाइप कन्वर्टमेथोड के चर को परिभाषित करने के लिए किया जा सकता है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.