Делегат ба үйл явдал 1.

Бид C# төрлийн бүрэлдхүүн хичээлүүдэд төрлийн Үйл явдлууд /Events/ ухагдхуунаас бусад гишүүдийг үзсэн. Иймээс энэ хичээлд Үйл явдлууд /Events/ ойлголтын талаар авч үзье. Үйл явдал делегат /delegate/ гэдэг ойлголт дээр суурилдаг учраас эхлээд делегат ухагдхууныг авч үзээд дараа нь үйл явдал гишүүний талаар авч үзье Delegate гэсэн үгийг монголчилбол "төлөөлөгч" гэж хэлж болох юм. Гэхдээ би делегат гэсэн нэрээр нь шууд ойлгон тогтоон авах нь илүү гэж үзлээ.

Signature - аргын тодорхойлогч

Эхлээд аргын "signature" гэсэн ухагдхуунтай танилцая. Үүнийг аргын тодорхойлогч гэж орчуулж болно. Аргын тодорхойлогч гэдэг нь түүний оролт, гаралтын параметрүүдийн төрөл ба дарааллыг хэлнэ. Үүнийг жишээн дээр харцгаая.

    public class Student
    {
        public string Move(int distance)
        {
            return null;
        }

        public int GetAge()
        {
            return 20;
        }

        public string Grow(int years)
        {
            return null;
        }

        public void SetInfo(string name, int age)
        {

        }

        public void SetSchool(int id, string number)
        {

        }
    }

Жишээнд Student классыг үзүүлсэн. Классын аргуудыг хэрхэн хэрэгжүүлсэн нь одоо бидэнд чухал биш харин тэдгээрийн тодорхойлолт чухал. Жишээний Move, Grow аргууд ижилхэн тодорхойлогчтой байгаа. Яагаад гэвэл эдгээр аргуудаас буцах утгууд ижилхэн string төрөлтэйн дээр оролтын параметрүүд бас ижилхэн int төрөлтэй. Хэдийгээр SetInfo, SetSchool аргуудад буцах утгын төрөл, оролтын параметрүүдийн төрлүүд ижилхэн боловч Move, Grow аргуудаас тодорхойлогчоороо ялгаатай. Учир нь SetInfo, SetSchool аргуудын оролтын параметрүүдийн дараалал өөр байгаа. Иймээс Student класст Move, Grow аргуудыг л ижилхэн тодорхойлогчтой гэж үзнэ. Өөрөөр аргын тодорхойлогчийг бүх параметрүүдийн төрлүүдийг агуулсан хэв байдлаар ойлгож болно. Ийм төрлийн хэдэн хэвийг доор үзүүллээ.

void (int, string) 
bool ()
DateTime (int)

Аргын тодорхойлогчид түүний нэр болон параметрүүдийн нэрүүд ямарч хамааралгүй зөвхөн оролт, гаралтын параметрүүдийн төрөл, дараалал гол үүрэгтэй.

Delegate - төлөөлөгч

Одоо делегат гэж юу болохыг авч үзье. Делегат бол нэгдүгээрт C# -ийн өгөгдлийн төрөл хоёрдугаар холбоосоор өгөгдөх /өөрөөр хэлбэл класс/ өгөгдлийн төрөл гуравдугаарт делегат бол тодорхойлогч нь түүний өөрийн зарлалтын тодорхойлолттой тохирч байгаа аргын холбоосыг хадгалж болдог өгөгдлийн төрөл. Доорх жишээг харна уу.

    public delegate int CountDelegate(string message);

    public class StringHelper
    {
        public int GetCount(string inputString)
        {
            return inputString.Length;
        }

        public int GetCountSymbolA(string inputString)
        {
            return inputString.Count(c => c == 'A');
        }

        public int GetCountSymbol(string inputString, char symbol)
        {
            return inputString.Count(c => c == symbol);
        }
    }

Жишээний эхний мөрөөр зарлагдсан CountDelegate нэртэй делегат string төрлийн ганцхан параметр аваад бүхэл тоон төрлийн утга буцаах аргын тодорхойлогчийг зарласан байгаа. Энд аргын нэр ба параметрийн нэрүүд ямарч хамааралгүй болно. Энэ тодорхойлогчид тохирох арга StringHelper класст хоёр байгаа нь GetCount, GetCountSymbolA аргууд юм. Харин GetCountSymbol арга оролтын хоёр параметртэй тул делегатын тодорхойлолтонд тохирохгүй.
Делегатыг классын төрөл гэж хэлсэн. Үүнийг шалгахын тулд програмаа компиляц хийгээд дизассемблерыг ажиллуулан MSIL кодыг харцгаавал

гэж харагдана. CountDelegate төрлийн зарлалтанд түүнийг class түлхүүр үгээр зарласан байгаа нь зураг дээрээс харагдана. Энэ нь CountDelegate төрөл бол класс гэдгийг илэрхийлнэ. CountDelegate класс учраас бид ийм төрлийн дурын хувьсагчийг зарлан ашиглаж болно. CountDelegate -ийг ашигласан жишээг харцгаана уу.

    class Program
    {
        static void Main(string[] args)
        {
            StringHelper helper = new StringHelper();

            CountDelegate d1 = helper.GetCount;
            CountDelegate d2 = helper.GetCountSymbolA;

            CountDelegate error = helper.GetCountSymbol;
        }
    }

Дээрх жишээнд бид CountDelegate төрлийн d1, d2 делегатыг зарласан. Эдгээр хувьсагчдын утгууд бол бидний өмнө нь зарласан делегатын тодорхойлолтонд / int (string) /тохирох аргуудын холбоос юм. GetCount, GetCountSymbolA аргууд делегаттай тохирох тодорхойлогчтойг бид мэдэх тул d1, d2 -д эдгээр утгуудыг өгч болно. Харин GetCountSymbol арга / int (string, char) / гэсэн өөр тодорхойлттой тул боловсруулалтын орчин алдаа өгнө. d1, d2 делегатыг хэрхэн ашиглахыг жишээг авч үзэцгээе.

using System;

namespace Lesson1
{
    class Program
    {
        static void Main(string[] args)
        {
            StringHelper helper = new StringHelper();

            CountDelegate d1 = helper.GetCount;
            CountDelegate d2 = helper.GetCountSymbolA;

            string testString = "LAMP";

            Console.WriteLine("Нийт тэмдэгтийн тоо: {0}", TestDelegate(d1, testString));
            Console.WriteLine("A тэмдэгтийн тоо: {0}", TestDelegate(d2, testString));

            Console.ReadLine();
        }

        static int TestDelegate(CountDelegate method, string testString)
        {
            return method(testString);
        }
    }
}

d1, d2 делегатыг ашиглахын тулд эхний параметрээр шалгах гэж буй аргын холбоосыг харин хоёрдахь параметрээр аргад ашиглах мөрийг авах TestDelegate аргыг зарлан өгье. Дараа нь аргуудад дамжуулах мөрийг string testString = "LAMP"; гэж зарлана. Консолд мөр гаргах эхний операторт TestDelegate аргыг дуудахдаа эхний параметрээр GetCount аргын холбоосыг хоёрдахь операторт GetCountSymbolA аргын холбоосыг өгсөн. Манай TestDelegate аргад юу хийгдэх вэ? Компилятор method хувьсагчаар дамжуулан дуудах аргын холбоосыг аваад түүний тодорхойлогчоор нь дуудна. Өөрөөр хэлбэл string төрлийн оролтын параметр аваад бүхэл тоон төрлийн утга буцаах аргыг дуудна. За ингээд програмаа ажлуулаад үзвэл

бид хүлээж байсан үр дүнгээ авна. Үнэхээр "LAMP" мөрний нийт тэмдэгт 4, мөрөнд "A" тэмдэгт нэг л байгаа. Танд ийм ердийн бус ажиллагаатай делегатууд юунд хэрэгтэй юм, тэдгээрийг хаана, хэрхэн ашигладаг юм вэ? гэсэн бодол төрж байгаа байх. Үүнийг энгийн жишээгээр тайлбарлая. Student класст Move аргыг тодорхойлон өгье.

    public class Student
    {
        public void Move(int distance)
        {
            for(int i=1; i<=distance; i++)
            {
                System.Threading.Thread.Sleep(1000);
                Console.WriteLine("Шилжилт хийгдэж байна... {0} километр явлаа.",i);
            }
        }
    }

Арга оролтын параметрээр явсан километрийн хэмжээг аваад явж өнгөрсөн зайн тухай мэдээллийг циклээр өгөх юм. Одоо Move аргыг үндсэн програмаас

    class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student();
            student.Move(10);
        }
    }

гэж дуудан ажлуулбал

үр дүнг өгнө. Бүгд хэвийн сайн ажиллаж байгаа биз. Одоо манай Student класс хаа нэг веб серверт байрлаж байгаа гэж бодъё. Энэ тохиолдолд бид класст хандан түүнээс мэдээллийг хүлээн аваад консолд биш интернетээр харуулах эсхүл бид ямар нэгэн Windows програм хийж байгаа бол мэдээллийг графикийн интерфейс бүхий цонхонд үзүүлэх хэрэгтэй болно. Ерөнхий санаа бол бид Move аргаас хүлээн авсан мэдээллийг харуулах аргаас хамааралгүйгээр түүнээс мэдээллийг авах байдлаар зохион байгуулах хэрэгтэй гэсэн үг. Яг үүнийг бид одоо делегатыг ашиглан хэрэгжүүлэх болно. Эхлээд делегатаа зарлан өгье.

    public delegate void ShowMessage(string message);

Бидэнд утга буцаахгүй харин string төрлийн ганцхан параметр аваад түүнтэй ажиллах арга шаардлагатай. Иймээс манай делегатын тодорхойлогч void (string) хэлбэртэй байна. Дараа нь Move аргад энэхүү делегатын хувьсагчийг дамжуулна.

    public void Move(int distance, ShowMessage method)

Өөрөөр хэлбэл тодорхойлогчид тохирох аргын холбоосыг дамжуулна. Одоо мэдээллийг консолд үзүүлэх мөрийг

    method(string.Format("Шилжилт хийгдэж байна... {0} километр явлаа.",i));

дамжин ирэх аргаар солино. Student классын кодыг үзүүлбэл

    public delegate void ShowMessage(string message);

    public class Student
    {
        public void Move(int distance, ShowMessage method)
        {
            for(int i=1; i<=distance; i++)
            {
                System.Threading.Thread.Sleep(1000);
                method(string.Format("Шилжилт хийгдэж байна... {0} километр явлаа.",i));
            }
        }
    }

болоод байгаа. Ингэснээр бид юунд хүрсэн вэ? Одоо Move арга өөрийн мэдээллийг консолд гаргахын оронд түүнийг ямар нэгэн өөр аргад дамжуулна. Ямар арга гэдгийг Move арга өөрөө ч мэдэхгүй. Түүнд энэ аргын холбоосыг удирдах код гаднаас өгсөн. Ингэснээр бид мэдээллийг хэрэглэгчийн интерфейст гаргах аргыг бүрэн хийсвэрлэж чадлаа. Энэхүү аргыг хэрхэн ашиглах вэ? Жишээний үндсэн кодыг харуулбал

namespace Lesson1
{
    class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student();
            student.Move(10);
        }
    }
}

байгаа. Одоо дараах өөрчлөлтийг хийе. Эхлээд делегатын void (string) тодорхойлогчид тохирох Show аргыг нэмнэ.

        static void Show(string message)
        {
            Console.WriteLine(message);
        }

Тэгэхлээр одоо түүний холбоосыг оруулах хэрэгтэй. Үүнийг

ShowMessage method = Show;

гэж хийнэ. Дээрх оператор манай Show аргын холбоосыг method хувьсагчид олгож байгаа юм. Одоо student классын Move аргад method хувьсагчийг хоёрдахь параметрээр өгцгөөе.

student.Move(10,method);

Ингээд гүйцээ. Манай үндсэн програмын код

namespace Lesson1
{
    class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student();

            ShowMessage method = Show;

            student.Move(10,method);
        }

        static void Show(string message)
        {
            Console.WriteLine(message);
        }
    }
}

хэлбэртэй болсон. Програмаа ажлуулбал

гэсэн яг ижилхэн үр дүнг авна. Кодыг анхааралтай ажиглабал одоо Show аргад мэдээллийг үзүүлэхдээ та веб интерфейс, десктоп интерфейсээр гэх мэтээр дурын аргыг ашиглах боломжтой болсон нь харагдана. Делегат ямар хэрэгтэйг ойлгосон гэж бодож байна. Энэ хичээлийг ингээд өндөрлөе. Дараагийн хичээлд үйл явдлын талаар үргэлжлүүлэн үзэх тул делегатын талаар сайн ойлгон аваарай.

Мэдээлэл таалагдсан бол найзуудтайгаа хуваалцаарай.

  Нээгдсэн тоо: 1212 Төлбөртэй

Entity Framework -ийн талаарх өмнөх хичээлүүдэд бид MSSQL серверт энгийн өгөгдлийн сан үүсгээд түүнд ADO NET -ээр хандах стандарт арга болон EF технологийг ашиглан хандахыг үзсэн. Entity Framework -ийг ашиглан өгөгдлийн санд хандах код нь стандарт аргаас хамаагүй бага бөгөөд уншин ойлгоход амархан байсныг харсан. Одоо програмын кодоос EF технологиор өгөгдлийн санд хандаж болох аргуудын талаар авч үзье.

  Нээгдсэн тоо: 2583 Төлбөртэй

Манай энэ удаагийн сэдэв сонирхолтой болоод нилээд хүнд лямбда илэрхийлэл байх болно. Лямбда илэрхийлэлтэй танилцахын өмнө делегат гэж юу болох талаар делегат ба үйл явдал хичээлээс үзэхийг зөвлөе. Делегатын талаар ойлголтгүйгээр та лямбда илэрхийлэл гэж юу болохыг ойлгоход их хүндрэлтэй. Делегат ба үйл явдал хэрхэн ажилладагийг доорх кодоос харцгаая.

  Нээгдсэн тоо: 1686 Төлбөртэй

Бид өмнөх хичээлээр битүүмжлэгдсэн, статик классуудын талаар үзсэн. ОХП-д классууд чухал үүрэгтэй нь ойлгомжтой. Иймээс класуудын төрлүүдийг мэдээд зогсохгүй тэдгээрийг хаана хэрхэн ашиглахыг маш зөв ойлговол таны код цэгцтэй, ойлгомжтой, өөрчлөлт, шинэчлэл хийхэд уян хатан болдог. 

Програмчлалын аргачлал Singleton

Статик арга, классыг хэрхэн ашиглах жишээ болгоод Singleton гэдэг өргөн дэлгэрсэн програмчлалын  аргачлалыг авч үзье. Програм зохиогчдын дунд энэхүү аргачлалын талаар эерэг, сөрөг янз бүрийн үзэл бодлууд байдаг гэдгийг хэлэх нь зүйтэй.

  Нээгдсэн тоо: 542 Төлбөртэй

Програмчлалын C# хэл хатуу төрөлжилттэй тул өгөгдөлтэй ажиллах үед null утга асуудал үүсгэх тохиолдол их. Үүнийг тооцолгүй бичигдсэн код бүр ажлын /production/ хувилбараар ажиллаж байхдаа алдаа өгөх тал бий. Кодийн тестийг хийхдээ тухайн хувьсагчид null утга олгогдох тохиолдолыг тооцохгүй байх нь ийм асуудал гарах үндсэн шалтгаан хэдий ч кодлогч энэ талаар өөрөө бодон кодлох хэрэгтэй.   

null -ийн шалгалт. Null guard /хамгаалагч/

Коддоо null утга авдаг өөрөөр хэлбэл nullable төрлийн хувьсагч болон параметрүүд ашиглах болбол NullReferenceException алдаа гарахаас сэргийлэн null -ийг шалгах хэрэгтэй. Жишээ нь

void PrintUpper(string? text)
{
    if (text!=null)
    {
        Console.WriteLine(text.ToUpper());
    }    
}

Дээрх кодод text параметр null -тэй тэнцүү биш бол мөрийн тэмдэгтүүдийг том үсэг болгох ToUpper() аргыг дуудна.

Үйл явдал /event/ тодорхой үйлдэл хийгдсэн талаар системд мэдэгддэг. Хэрвээ бид энэхүү үйлдлийг ажиглах хэрэгтэй бол яг энд…

Нээгдсэн тоо : 307

 

Манай төсөл олон хуудсуудтай болон тэдгээрийн хооронд динамикаар шилжилт хийж байгаа ч тухайн үед шилжилт хийгдсэн хуудаст тохирох…

Нээгдсэн тоо : 406

 

Зочин (Visitor) паттерн классуудыг өөрчлөхгүйгээр тэдгээрийн обьектуудын үйлдлийг тодорхойлох боломжийг олгоно. Зочин хэвийг ашиглахдаа классуудын хоёр ангилалыг тодорхойлно.…

Нээгдсэн тоо : 354

 

Лямбда-илэрхийлэл нь нэргүй аргын хураангуй бичилтийг илэрхийлнэ. Лямбда-илэрхийлэл утга буцаадаг, буцаасан утгыг өөр аргын…

Нээгдсэн тоо : 448

 

Кодийн сайжруулалт /рефакторинг/ хичээлээр програмийн кодоо react -ийн зарчимд нийцүүлэн компонентод салгасан.…

Нээгдсэн тоо : 522

 

Хадгалагч (Memento) хэв обьектын дотоод төлвийг түүний гадна гаргаж дараа нь хайрцаглалтын зарчмыг зөрчихгүйгээр обьектыг сэргээх боломжийг олгодог.

Нээгдсэн тоо : 519

 

Делегаттай нэргүй арга нягт холбоотой. Нэргүй аргуудыг делегатийн хувийг үүсгэхэд ашигладаг.
Нэргүй аргуудын тодорхойлолт delegate түлхүүр үгээр…

Нээгдсэн тоо : 622

 

Математикт харилцан урвуу тоонууд гэж бий. Ямар нэгэн тооны урвуу тоог олохдоо тухайн тоог сөрөг нэг зэрэг дэвшүүлээд…

Нээгдсэн тоо : 713

 

Төсөлд react-router-dom санг оруулан чиглүүлэгчдийг бүртгүүлэн тохируулсан Санг суулган тохируулах хичээлээр бид хуудас…

Нээгдсэн тоо : 750

 
Энэ долоо хоногт

задаргааны хамгийн их нэмэгдхүүн бол a, b, c -г ол.

Нээгдсэн тоо : 1550

 

тэгшитгэлийг бод.

Нээгдсэн тоо : 1207

 

функцийн уламжлалын утгыг ол.

Нээгдсэн тоо : 451