C# Language
लैंबडा एक्सप्रेशन
खोज…
टिप्पणियों
बंद
लैम्ब्डा के भाव स्पष्ट रूप से इस्तेमाल किए गए चर को कैप्चर करेंगे और एक क्लोजर बनाएंगे । एक समापन कुछ राज्य के संदर्भ के साथ एक समारोह है। जब भी लैम्बडा एक्सप्रेशन 'अपने आसपास के संदर्भ से एक मान को' घेरता है, तो कंपाइलर एक क्लोजर उत्पन्न करेगा।
जैसे जब निम्नलिखित निष्पादित किया जाता है
Func<object, bool> safeApplyFiltererPredicate = o => (o != null) && filterer.Predicate(i);
safeApplyFilterPredicate
एक नए बनाए गए ऑब्जेक्ट को संदर्भित करता है जिसमें filterer
के वर्तमान मूल्य का एक निजी संदर्भ filterer
, और जिसका Invoke
विधि व्यवहार करता है
o => (o != null) && filterer.Predicate(i);
यह महत्वपूर्ण हो सकता है, क्योंकि जब तक safeApplyFilterPredicate
में अब मूल्य का संदर्भ बनाए रखा जाता है, तब तक उस ऑब्जेक्ट का एक संदर्भ होगा जिसे filterer
वर्तमान में संदर्भित करता है। इससे कचरा संग्रहण पर प्रभाव पड़ता है, और यदि कोई वस्तु जो filterer
संदर्भित करता है, तो उत्परिवर्तित होने पर अप्रत्याशित व्यवहार हो सकता है।
दूसरी ओर, किसी व्यवहार को रोकने के लिए क्लोजर का उपयोग जानबूझकर प्रभाव के लिए किया जा सकता है जिसमें अन्य वस्तुओं के संदर्भ शामिल हैं।
उदाहरण के लिए
var logger = new Logger();
Func<int, int> Add1AndLog = i => {
logger.Log("adding 1 to " + i);
return (i + 1);
};
क्लोजर का उपयोग राज्य मशीनों को मॉडल करने के लिए भी किया जा सकता है:
Func<int, int> MyAddingMachine() {
var i = 0;
return x => i += x;
};
मूल लंबोदर भाव
Func<int, int> add1 = i => i + 1;
Func<int, int, int> add = (i, j) => i + j;
// Behaviourally equivalent to:
int Add1(int i)
{
return i + 1;
}
int Add(int i, int j)
{
return i + j;
}
...
Console.WriteLine(add1(42)); //43
Console.WriteLine(Add1(42)); //43
Console.WriteLine(add(100, 250)); //350
Console.WriteLine(Add(100, 250)); //350
LINQ के साथ मूलभूत लंबोदर भाव
// assume source is {0, 1, 2, ..., 10}
var evens = source.Where(n => n%2 == 0);
// evens = {0, 2, 4, ... 10}
var strings = source.Select(n => n.ToString());
// strings = {"0", "1", ..., "10"}
एक क्लोजर बनाने के लिए लैम्ब्डा सिंटैक्स का उपयोग करना
क्लोजर की चर्चा के लिए टिप्पणी देखें। मान लीजिए कि हमारे पास एक इंटरफ़ेस है:
public interface IMachine<TState, TInput>
{
TState State { get; }
public void Input(TInput input);
}
और फिर निम्नलिखित को निष्पादित किया जाता है:
IMachine<int, int> machine = ...;
Func<int, int> machineClosure = i => {
machine.Input(i);
return machine.State;
};
अब machineClosure
से एक समारोह को संदर्भित करता है int
के लिए int
है, जो पर्दे के पीछे का उपयोग करता IMachine
उदाहरण है, जिसमें machine
क्रम गणना को पूरा करने के लिए संदर्भित करता है। यहां तक कि अगर संदर्भ machine
गुंजाइश से बाहर जाती है, तो जब तक machine
machineClosure
ऑब्जेक्ट बनाए रखा जाता है, मूल IMachine
उदाहरण को 'क्लोजर' के हिस्से के रूप में रखा जाएगा, जो स्वचालित रूप से कंपाइलर द्वारा परिभाषित किया गया है।
चेतावनी: इसका मतलब यह हो सकता है कि एक ही फ़ंक्शन कॉल अलग-अलग समय पर अलग-अलग मान लौटाता है (जैसे इस उदाहरण में यदि मशीन अपने इनपुट का एक योग रखता है)। बहुत सारे मामलों में, यह अप्रत्याशित हो सकता है और कार्यात्मक शैली में किसी भी कोड के लिए टाला जा सकता है - आकस्मिक और अप्रत्याशित बंद बग का स्रोत हो सकता है।
बयान ब्लॉक बॉडी के साथ लैम्ब्डा सिंटैक्स
Func<int, string> doubleThenAddElevenThenQuote = i => {
var doubled = 2 * i;
var addedEleven = 11 + doubled;
return $"'{addedEleven}'";
};
System.Linq.Expressions के साथ लैम्ब्डा एक्सप्रेशन
Expression<Func<int, bool>> checkEvenExpression = i => i%2 == 0;
// lambda expression is automatically converted to an Expression<Func<int, bool>>