एक बार संकलित करने के बाद, क्या इसमें अंतर है:
delegate { x = 0; }
तथा
() => { x = 0 }
?
एक बार संकलित करने के बाद, क्या इसमें अंतर है:
delegate { x = 0; }
तथा
() => { x = 0 }
?
जवाबों:
संक्षिप्त उत्तर: नहीं।
लंबा जवाब जो प्रासंगिक नहीं हो सकता है:
Func
या) के लिए लैम्ब्डा असाइन करते हैंAction
) के तो आपको एक अनाम प्रतिनिधि मिलेगा।संपादित करें: यहां एक्सप्रेशन के लिए कुछ लिंक दिए गए हैं।
मुझे एमी का जवाब पसंद है, लेकिन मुझे लगा कि मुझे पांडित्य होगा। प्रश्न कहता है, "एक बार यह संकलित किया जाता है" - जो बताता है कि दोनों अभिव्यक्तियों को संकलित किया गया है। वे दोनों कैसे संकलित कर सकते हैं, लेकिन एक प्रतिनिधि के रूप में और एक को अभिव्यक्ति पेड़ में परिवर्तित किया जा सकता है? यह एक मुश्किल है - आपको गुमनाम तरीकों की एक और विशेषता का उपयोग करना होगा; केवल वही जो लंबोदर भावों द्वारा साझा नहीं किया गया है। यदि आप किसी पैरामीटर सूची को निर्दिष्ट किए बिना एक अनाम विधि निर्दिष्ट करते हैं , तो यह किसी भी प्रतिनिधि प्रकार के रिटर्निंग शून्य और बिना किसी out
पैरामीटर के संगत है । इस ज्ञान के साथ सशस्त्र, हमें अभिव्यक्तियों को पूरी तरह से अस्पष्ट लेकिन बहुत अलग बनाने के लिए दो अधिभार का निर्माण करने में सक्षम होना चाहिए।
लेकिन आपदा आघात! कम से कम C # 3.0 के साथ, आप एक लैम्ब्डा एक्सप्रेशन को ब्लॉक बॉडी के साथ एक एक्सप्रेशन में नहीं बदल सकते - और न ही आप लैम्बडा एक्सप्रेशन को बॉडी में असाइनमेंट के साथ बदल सकते हैं (भले ही इसे रिटर्न वैल्यू के रूप में इस्तेमाल किया जाए)। यह C # 4.0 और .NET 4.0 के साथ बदल सकता है, जो अभिव्यक्ति ट्री में अधिक व्यक्त होने की अनुमति देता है। तो दूसरे शब्दों में, MojoFilter देने के लिए उदाहरणों के साथ, दोनों को लगभग हमेशा एक ही चीज़ में बदल दिया जाएगा। (एक मिनट में अधिक जानकारी।)
हम प्रतिनिधि मापदंडों चाल का उपयोग कर सकते हैं यदि हम निकायों को थोड़ा बदल देते हैं:
using System;
using System.Linq.Expressions;
public class Test
{
static void Main()
{
int x = 0;
Foo( () => x );
Foo( delegate { return x; } );
}
static void Foo(Func<int, int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
static void Foo(Expression<Func<int>> func)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
लेकिन रुकें! हम अभिव्यक्ति के पेड़ों का उपयोग किए बिना भी दोनों के बीच अंतर कर सकते हैं, अगर हम पर्याप्त रूप से चालाक हों। नीचे दिए गए उदाहरण में अधिभार संकल्प नियमों (और अनाम प्रतिनिधि मिलान चाल) का उपयोग किया गया है ...
using System;
using System.Linq.Expressions;
public class Base
{
public void Foo(Action action)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
public class Derived : Base
{
public void Foo(Action<int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int x = 0;
d.Foo( () => { x = 0; } );
d.Foo( delegate { x = 0; } );
}
}
आउच। बच्चों को याद रखें, हर बार जब आप बेस क्लास से विरासत में मिली विधि को ओवरलोड करते हैं, तो थोड़ा बिल्ली का बच्चा रोने लगता है।
delegate { ... }
यह समान नहीं है delegate() { ... }
- उत्तरार्द्ध केवल एक पैरामीटर रहित प्रतिनिधि प्रकार के साथ संगत है।
ऊपर के दो उदाहरणों में कोई अंतर नहीं है, शून्य।
भाव:
() => { x = 0 }
स्टेटमेंट बॉडी के साथ एक लैम्ब्डा एक्सप्रेशन है, इसलिए इसे एक्सप्रेशन ट्री के रूप में संकलित नहीं किया जा सकता है। वास्तव में यह संकलन भी नहीं करता है क्योंकि इसे 0 के बाद अर्धविराम की आवश्यकता होती है:
() => { x = 0; } // Lambda statement body
() => x = 0 // Lambda expression body, could be an expression tree.
एमी बी सही है। ध्यान दें कि अभिव्यक्ति पेड़ों का उपयोग करने के लिए फायदे हो सकते हैं। LINQ to SQL एक्सप्रेशन ट्री की जाँच करेगा और इसे SQL में बदलेगा।
प्रभावी ढंग से रिफैक्टिंग-सुरक्षित तरीके से कक्षा सदस्यों के नाम को एक फ्रेमवर्क में पास करने के लिए आप लामाओं और अभिव्यक्ति पेड़ों के साथ चालें भी खेल सकते हैं। Moq इसका एक उदाहरण है।
इसमे अंतर है
उदाहरण:
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(delegate
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
और मैं लैम्ब्डा से प्रतिस्थापित करता हूं: (त्रुटि)
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(()=>
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
यहाँ कुछ मूल बातें।
यह एक अनाम विधि है
(string testString) => { Console.WriteLine(testString); };
चूंकि अनाम विधियों में नाम नहीं होते हैं इसलिए हमें एक प्रतिनिधि की आवश्यकता होती है जिसमें हम इन विधियों या अभिव्यक्तियों को निर्दिष्ट कर सकते हैं। जैसे
delegate void PrintTestString(string testString); // declare a delegate
PrintTestString print = (string testString) => { Console.WriteLine(testString); };
print();
लंबोदर अभिव्यक्ति के साथ भी। आमतौर पर हमें उनका उपयोग करने के लिए एक प्रतिनिधि की आवश्यकता होती है
s => s.Age > someValue && s.Age < someValue // will return true/false
हम इस अभिव्यक्ति का उपयोग करने के लिए एक फंक प्रतिनिधि का उपयोग कर सकते हैं।
Func< Student,bool> checkStudentAge = s => s.Age > someValue && s.Age < someValue ;
bool result = checkStudentAge ( Student Object);