अनाम विधि से मान कैसे लौटाएं?


89

यह विफल हो जाता है

string temp = () => {return "test";};

त्रुटि के साथ

लैंबडा अभिव्यक्ति को 'स्ट्रिंग' टाइप करने के लिए परिवर्तित नहीं किया जा सकता है क्योंकि यह एक प्रतिनिधि प्रकार नहीं है

त्रुटि का क्या मतलब है और मैं इसे कैसे हल कर सकता हूं?


यह प्रश्न Google में पहला परिणाम क्यों है जब त्रुटि की खोज "अनाम फ़ंक्शन एक शून्य रिटर्निंग प्रतिनिधि में परिवर्तित हो जाती है" जब कोई मूल्य वापस नहीं कर सकता है "तो स्पष्ट रूप से इसका कोई लेना देना नहीं है?"
कैलमेरियस जूल

जवाबों:


136

यहाँ समस्या यह है कि आपने एक अनाम विधि परिभाषित की है जो वापस लौटती है stringलेकिन इसे सीधे a में निर्दिष्ट करने का प्रयास कर रहे हैं string। यह एक अभिव्यक्ति है जो जब आह्वान करती है तो stringयह सीधे तौर पर नहीं होती है string। इसे एक संगत प्रतिनिधि प्रकार को सौंपा जाना चाहिए। इस मामले में सबसे आसान विकल्प हैFunc<string>

Func<string> temp = () => {return "test";};

यह एक पंक्ति में थोड़ा सा कास्टिंग या प्रतिनिधि निर्माता का उपयोग करके लंबोदा के प्रकार को स्थापित करने के लिए किया जा सकता है।

string temp = ((Func<string>)(() => { return "test"; }))();
string temp = new Func<string>(() => { return "test"; })();

नोट: दोनों नमूनों को अभिव्यक्ति के रूप में छोटा किया जा सकता है जिसमें कमी है { return ... }

Func<string> temp = () => "test";
string temp = ((Func<string>)(() => "test"))();
string temp = new Func<string>(() => "test")();

धन्यवाद। तो एक लाइन पर सब कुछ करने का कोई तरीका नहीं (स्ट्रिंग निर्दिष्ट करने सहित)? मैं जो मूल्य चाहता हूं ("परीक्षण", जो वास्तव में वास्तविक जीवन में एक चर है) एक और मेमने के अंदर है इसलिए मैं ढीली गुंजाइश करता हूं अगर मैं ऊपर दिए अनुसार आपको परिभाषित करने की कोशिश करता हूं।
4thSpace

@ 4thSpace यह कुछ बुराई कास्टिंग के साथ एक पंक्ति में किया जा सकता है। मैंने रास्ता दिखाने के लिए अपने जवाब को अपडेट किया
जेरेडपर

या इस मामले में, बस Func<string> temp = () => "test";
गाबे

या आपके संपादन के मामले में,string temp = new Func<string>(() => "test")();
गेबे

उत्तम! अगर मैं एक इंट में पास होना चाहता था, तो क्या आप उसे एक लाइन में दिखा सकते हैं? मैंने यह कोशिश की, लेकिन नहीं जाना: ((फंक <int, string>) ((4) => {वापसी "परीक्षण";})) ();
4thSpace

15

आप एक स्ट्रिंग प्रकार के एक प्रतिनिधि को सौंपने का प्रयास कर रहे हैं । इसे इस्तेमाल करे:

Func<string> temp = () => {return "test";};

अब आप फ़ंक्शन को इस प्रकार निष्पादित कर सकते हैं:

string s = temp();

"S" वेरिएबल का अब मान "परीक्षण" होगा।


1
यह संकलित नहीं करता है: "स्पष्ट रूप से टाइप किए गए स्थानीय चर के लिए लैम्ब्डा अभिव्यक्ति नहीं दे सकता है"
डेव बिश

@Dave: दिलचस्प, उस सीमा के बारे में पता नहीं था। अद्यतन, धन्यवाद!
डेव स्वर्सकी

8

एक छोटे सहायक समारोह और जेनरिक का उपयोग करके आप कंपाइलर को टाइप का अनुमान लगा सकते हैं, और इसे थोड़ा छोटा कर सकते हैं:

public static TOut FuncInvoke<TOut>(Func<TOut> func)
{
    return func();
}

var temp = FuncInvoke(()=>"test");

साइड नोट: यह तब भी अच्छा है जब आप एक अनाम प्रकार वापस करने में सक्षम हैं:

var temp = FuncInvoke(()=>new {foo=1,bar=2});

दिलचस्प तकनीक। क्या यह रन-टाइम ओवरहेड जोड़ता है, या यह सब संकलन समय पर है?
टूलमेकरसेव

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

@ToolmakerSteve प्रदर्शन प्रभाव पर उस अंतिम "अनुमान" से आगे बढ़ने के बाद, मैं यह जोड़ूंगा कि प्रदर्शन पर भी सबसे खराब स्थिति का प्रभाव लगभग शून्य होगा (एक गैर-आभासी, स्थिर विधि के लिए एक अतिरिक्त फ़ंक्शन कॉल)। इस तकनीक का उपयोग करने वाला कोई भी व्यक्ति ऐसा करने की संभावना है क्योंकि वे लंबोदा को चारों ओर फेंक रहे हैं। इसका मतलब है कि वे शायद कम से कम LINQ विस्तार विधियों का उपयोग कर रहे हैं, इसलिए संभावनाएँ बहुत अच्छी हैं कि वे अनजाने में LINQ तरीकों की एक जोड़ी को एक तरह से जंजीर में डाल दिया है, जो एक अतिरिक्त फ़ंक्शन कॉल की तुलना में प्रदर्शन को 100,000 गुना बदतर बना देता है ;)
डैनियल स्कॉट

5

आप अनाम पद्धति का उपयोग तर्क के साथ कर सकते हैं:

int arg = 5;

string temp = ((Func<int, string>)((a) => { return a == 5 ? "correct" : "not correct"; }))(arg);

आप कर सकते हैं, लेकिन कृपया बताएं कि यह प्रश्न का उत्तर कैसे है।
टूलमेकरसेव

2

एक अनाम विधि एक मानदंड प्रतिनिधि का उपयोग कर एक मान लौटा सकती है। यहां एक उदाहरण है जहां मैंने दिखाया है कि एक अनाम विधि का उपयोग करके एक मूल्य कैसे वापस किया जाए।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {


        static void Main(string[] args)
        {
            Func<int, int> del = delegate (int x)
              {
                  return x * x;

              };

            int p= del(4);
            Console.WriteLine(p);
            Console.ReadLine();
        }
    }
}

0

यह C # 8 का उपयोग करके एक और उदाहरण है ( समानांतर कार्यों का समर्थन करने वाले अन्य .NET संस्करणों के साथ भी काम कर सकता है )

using System;
using System.Threading.Tasks;

namespace Exercise_1_Creating_and_Sharing_Tasks
{
    internal static class Program
    {
        private static int TextLength(object o)
        {
            Console.WriteLine($"Task with id {Task.CurrentId} processing object {o}");
            return o.ToString().Length;
        }

        private static void Main()
        {
            const string text1 = "Welcome";
            const string text2 = "Hello";

            var task1 = new Task<int>(() => TextLength(text1));
            task1.Start();

            var task2 = Task.Factory.StartNew(TextLength, text2);

            Console.WriteLine($"Length of '{text1}' is {task1.Result}");
            Console.WriteLine($"Length of '{text2}' is {task2.Result}");

            Console.WriteLine("Main program done");
            Console.ReadKey();
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.