खोज…


टिप्पणियों

बंद

लैम्ब्डा के भाव स्पष्ट रूप से इस्तेमाल किए गए चर को कैप्चर करेंगे और एक क्लोजर बनाएंगे । एक समापन कुछ राज्य के संदर्भ के साथ एक समारोह है। जब भी लैम्बडा एक्सप्रेशन 'अपने आसपास के संदर्भ से एक मान को' घेरता है, तो कंपाइलर एक क्लोजर उत्पन्न करेगा।

जैसे जब निम्नलिखित निष्पादित किया जाता है

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>>


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow