Dec 13, 2013

Lambda Expressions


Lambda expressions არის ძალიან კარგი თვისებაა C# 3.0 ისა, ხოლო ასევე ის შეიძლება იყოს დიდი საფრთხის შემცველი იმისათვის, ვინც არ იცი როგორ გამოიყენოს შესაბამისად ისინი. ეს პოსტი იმათთვის იქნება გასაგები ვინც იცის თუ რა არის დელეგატი და როგორ გამოიყენება ის. C# იყენებს ახალ სინტაქსს, რომლითაც კოდის წერა უფრო დახვეწილი, ლამაზი და ერთგვარად ძლიერი ხდება. ჩვენ გვქონდა მაგალითი წინა პოტიდან, სადაც გამოვიყენე ანონიმური მეთოდი, ახლა ცოტა შევცვალოთ ეს ყველაფერი.

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

namespace BlogSpotAppConsole
{
    class Program
    {
        static void Main()
        {
            int num1 = 10;
            //Func<int, int> anonDel = delegate(int param)
            //{
            //    param += 12;
            //    param += 32;
            //    return param;
            //};

            //Console.WriteLine(anonDel(num1));
            //Console.ReadKey();

            Func<int, int> lambdaEx = param =>
                {
                    param = num1;
                    param += 12;
                    param += 32;
                    return param;
                };
 
            Console.WriteLine(lambdaEx(num1));
            Console.ReadKey();
        }
    }
}

მოცემულ კოდში ანონიმური მეთოდის გამოყენება დაკომენტარებულია და მის მაგივრად ვიყენებ lambda expressions ს. „ =>“ ოპერატორს ეწოდება lambda ოპერატორი, რომლის მარცხნივ თავს იყრის ის პარამეტრები, რომლებიც საჭიროა, ხოლო მარჯვენა მხარე განკუთვნილია მეთოდის იმპლემენტაციისთვის, რომელიც ენიშნება lambdaEx ცვლადს, ჩემს შემთხვევაში.

აქ რამდენიმე საკითხია, რომელზეც მინდა ყურადღების გამახვილება  და მათი ცოტა უფრო დაწვრილებით განხილვა, მათ შორისაა პარამეტრები, და ცვლადები lambda Expression ის გარეთ.

დავიწყოთ პირველით - პარამეტრები

თუ მეთოდი შეიცავს მხოლოდ ერთ ხაზს, მაშინ ფიგურული ფრჩხილების გამოყენება აღარ წარმოადგენს საჭიროებას, ასევე არ არის საჭირო return ის მითითებაც, რადგან ერთ ხაზიანი მეთოდის დაწერისას return არაცხადად ჯდება კოდში კომპილატორის მიერ. მაგალითისათვის, გვაქვს კვადრატში აყვანის მეთოდი

Func<int, int> square = x => x * x;

რა თქმა უნდა შეიძლება თავის ატკიება და ზემოთ მოცემული დელეგატის გადატვირთვა, რაც იმას ნიშნავს, რომ გვექნება ფიგურული ფრჩხილებიც და დაბრუნების განაცხადიც

Func<int, int> Lsquare = x =>
                {
                    int temp = x * x;
                    return temp;
                };

მაგრამ უნდა დაიმახსოვროთ, რომ ფიგურული ფრჩხილებისა და დაბრუნების განაცხადის გამოყენება ვალდებულებაა ისეთი „მეთოდის“ იმპლემენტაციისთვის, რომელიც ერთზე მეტ ხაზს შეიცავს.

გავაგრძელოთ მეორე საკითხით - ცვლადები lambda expression ის გარეთ

Lambda expression ების გამოყენებით შესაძლებელია იმ ცვლადებზე წვდომა, რომლებიც განსაზღვრულია Lambda expression ის ბლოკის გარეთ. ეს ძალიან მაგარი თვისებაა, მაგრამ უნდა გამოიყენოთ სწორედ.

მაგალითში Lambda expression, რომლის ტიპია Func<int, int> მოითხოვს ერთ int ტიპის პარამეტრს და აბრუნებს იმავე ტიპისას. Lambda expression ისთვის პარამეტრი განსაზღვრულია როგორც x. ასევე Lambda expression ის კოდი იყენებს გარე ცვლადს num1 ს. კოდს, რომ შეხედოთ დაბრუნებული რიცხვი უნდა იყოს 5 + x.
 
 int num1 = 5;
            Func<int, int> f = x => x + num1;

მოდით ვნახოთ რა ხდება სინამდვილეში და რას აკეთებს კომპილატორი, რომ ჩვენთვის საქმის გამარტივებით შეასრულოს ასეთი ერთი შეხედვით მარტივი და კომფორტული სამუშაო. ამის გასაგებად x => x + num1, კომპილატორი ქმნის ანონიმურ კლასს, რომელსაც აქვს კონსტრუქტორი, რომელიც არგუმენტად იღებს გარე ცვლადებს, რომელიც lambda Expression ის გარეთ არის განსაზღვრული, ამ შემთხვევაში int ტიპის. კონსტრუქტორი გვარობა გამოკიდებულია იმაზე, თუ რამდენ ცვლადს იღებს დელეგატი. შექმნილი კლასი კი ასე გამოიყურება

public class AnonymousClass
{
    private int num1;

    public AnonymousClass(int num1)
    {
        this.num1 = num1;
    }
 
    public int AnonymousMethod(int x)
    {
        return x + num1;
    }
}
Lambda expression ების გამოყენება ასევე შესაძლებელია LINQ ში, დელეგატების გარდა.

No comments:

Post a Comment