Delegasi Predikat dalam C #

256

Bisakah Anda jelaskan kepada saya:

  • Apa yang dimaksud dengan Delegasi Predikat?
  • Di mana kita harus menggunakan predikat?
  • Adakah praktik terbaik saat menggunakan predikat?

Kode sumber deskriptif akan dihargai.

Canavar
sumber

Jawaban:

319

Predikat adalah fungsi yang mengembalikan trueatau false. Delegasi predikat adalah referensi ke predikat.

Jadi pada dasarnya delegasi predikat adalah referensi ke fungsi yang mengembalikan trueatau false. Predikat sangat berguna untuk memfilter daftar nilai - ini adalah contohnya.

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> list = new List<int> { 1, 2, 3 };

        Predicate<int> predicate = new Predicate<int>(greaterThanTwo);

        List<int> newList = list.FindAll(predicate);
    }

    static bool greaterThanTwo(int arg)
    {
        return arg > 2;
    }
}

Sekarang jika Anda menggunakan C # 3 Anda dapat menggunakan lambda untuk mewakili predikat dengan cara yang lebih bersih:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> list = new List<int> { 1, 2, 3 };

        List<int> newList = list.FindAll(i => i > 2);
    }
}
Andrew Hare
sumber
@Andrew Hare: di cuplikan kode pertama Anda, apakah itu seharusnya yeild return? Atau bagaimana cara kerjanya, bagaimana cara mengulangi seluruh daftar?
VoodooChild
5
@VoodooChild: Ingat bahwa predikat akan dipanggil untuk setiap elemen dalam urutan pada gilirannya . Jadi greaterThanTwomemiliki returntidak yield returnkarena merupakan FindAllmetode yang menangani urutan untuk Anda.
Andrew Hare
1
@AndrewHare, apakah mungkin untuk memiliki i > val, alih-alih i > 2, di mana valnilai dimasukkan oleh pengguna.
Mourya
81

Memimpin dari jawaban Andrew terkait dengan c # 2 dan c # 3 ... Anda juga dapat melakukannya sebaris untuk fungsi pencarian satu kali (lihat di bawah).

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> list = new List<int> { 1, 2, 3 };

        List<int> newList = list.FindAll(delegate(int arg)
                           {
                               return arg> 2;
                           });
    }
}

Semoga ini membantu.

WestDiscGolf
sumber
11

Hanya seorang delegasi yang mengembalikan boolean. Ini banyak digunakan dalam daftar pemfilteran tetapi dapat digunakan di mana pun Anda inginkan.

List<DateRangeClass>  myList = new List<DateRangeClass<GetSomeDateRangeArrayToPopulate);
myList.FindAll(x => (x.StartTime <= minDateToReturn && x.EndTime >= maxDateToReturn):
Adam Carr
sumber
9

Ada artikel bagus tentang predikat di sini , meskipun berasal dari era .NET2, jadi tidak disebutkan ekspresi lambda di sana.

LukeH
sumber
Tautan dalam jawaban Anda tidak lagi terhubung ke artikel yang sebenarnya
David Cram
@ David Cram: Terima kasih, saya telah memperbarui tautan untuk menggunakan Mesin Wayback, meskipun artikelnya terlihat sangat ketinggalan zaman saat ini.
LukeH
6

Apa itu Predikat Delegasi?

1) Predikat adalah fitur yang mengembalikan benar atau salah. Konsep ini telah masuk dalam kerangka .net 2.0. 2) Ini digunakan dengan ekspresi lambda (=>). Dibutuhkan tipe generik sebagai argumen. 3) Ini memungkinkan fungsi predikat untuk didefinisikan dan diteruskan sebagai parameter ke fungsi lain. 4) Ini adalah kasus khusus dari a Func, karena hanya membutuhkan satu parameter dan selalu mengembalikan bool.

Di C # namespace:

namespace System
{   
    public delegate bool Predicate<in T>(T obj);
}

Ini didefinisikan dalam System namespace.

Di mana kita harus menggunakan Delicate Predicate?

Kami harus menggunakan Predicate Delegate dalam kasus berikut:

1) Untuk mencari item dalam koleksi generik. misalnya

var employeeDetails = employees.Where(o=>o.employeeId == 1237).FirstOrDefault();

2) Contoh dasar yang memperpendek kode dan mengembalikan benar atau salah:

Predicate<int> isValueOne = x => x == 1;

sekarang, Panggil predikat di atas:

Console.WriteLine(isValueOne.Invoke(1)); // -- returns true.

3) Metode anonim juga dapat ditugaskan untuk jenis delegasi Predikat seperti di bawah ini:

Predicate<string> isUpper = delegate(string s) { return s.Equals(s.ToUpper());};
    bool result = isUpper("Hello Chap!!");

Adakah praktik terbaik tentang predikat?

Gunakan Func, Ekspresi Lambda, dan Delegasi alih-alih Predikat.

Gul Md Irsyad
sumber
5

Metode pencarian berbasis predikat memungkinkan delegasi metode atau ekspresi lambda untuk memutuskan apakah elemen yang diberikan adalah "cocok." Predikat hanyalah delegasi yang menerima objek dan mengembalikan benar atau salah: public delegate bool Predicate (objek T);

   static void Main()
        {
            string[] names = { "Lukasz", "Darek", "Milosz" };
            string match1 = Array.Find(names, delegate(string name) { return name.Contains("L"); });
            //or
            string match2 = Array.Find(names, delegate(string name) { return name.Contains("L"); });
            //or
            string match3 = Array.Find(names, x => x.Contains("L"));


            Console.WriteLine(match1 + " " + match2 + " " + match3);     // Lukasz Lukasz Lukasz
        }
        static bool ContainsL(string name) { return name.Contains("L"); }
lukaszk
sumber
2

Jika Anda berada di VB 9 (VS2008), predikat dapat menjadi fungsi yang kompleks:

Dim list As New List(Of Integer)(New Integer() {1, 2, 3})
Dim newList = list.FindAll(AddressOf GreaterThanTwo)
...
Function GreaterThanTwo(ByVal item As Integer) As Boolean
    'do some work'
    Return item > 2
End Function

Atau Anda dapat menulis predikat sebagai lambda, asalkan hanya satu ungkapan:

Dim list As New List(Of Integer)(New Integer() {1, 2, 3})
Dim newList = list.FindAll(Function(item) item > 2)
danlash
sumber
0

Predikat berada di bawah kategori delegasi umum di C #. Ini disebut dengan satu argumen dan selalu mengembalikan tipe boolean. Pada dasarnya, predikat digunakan untuk menguji kondisi - benar / salah. Banyak kelas mendukung predikat sebagai argumen. Untuk eg, list.findall mengharapkan predikat parameter. Berikut adalah contoh predikatnya.

Bayangkan sebuah pointer fungsi dengan tanda tangan -

delegasi bool myDelegate (pertandingan T);

Inilah contohnya

Node.cs

namespace PredicateExample
{
    class Node
    {
        public string Ip_Address { get; set; }
        public string Node_Name { get; set; }
        public uint Node_Area { get; set; }
    }
}

Kelas utama -

using System;
using System.Threading;
using System.Collections.Generic;

namespace PredicateExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Predicate<Node> backboneArea = Node =>  Node.Node_Area == 0 ;
            List<Node> Nodes = new List<Node>();
            Nodes.Add(new Node { Ip_Address = "1.1.1.1", Node_Area = 0, Node_Name = "Node1" });
            Nodes.Add(new Node { Ip_Address = "2.2.2.2", Node_Area = 1, Node_Name = "Node2" });
            Nodes.Add(new Node { Ip_Address = "3.3.3.3", Node_Area = 2, Node_Name = "Node3" });
            Nodes.Add(new Node { Ip_Address = "4.4.4.4", Node_Area = 0, Node_Name = "Node4" });
            Nodes.Add(new Node { Ip_Address = "5.5.5.5", Node_Area = 1, Node_Name = "Node5" });
            Nodes.Add(new Node { Ip_Address = "6.6.6.6", Node_Area = 0, Node_Name = "Node6" });
            Nodes.Add(new Node { Ip_Address = "7.7.7.7", Node_Area = 2, Node_Name = "Node7" });

            foreach( var item in Nodes.FindAll(backboneArea))
            {
                Console.WriteLine("Node Name " + item.Node_Name + " Node IP Address " + item.Ip_Address);
            }

            Console.ReadLine();
        }
    }
}
tangkas
sumber
0

Cukup -> mereka memberikan nilai Benar / Salah berdasarkan kondisi yang sebagian besar digunakan untuk kueri. kebanyakan digunakan dengan delegasi

pertimbangkan contoh daftar

List<Program> blabla= new List<Program>();
        blabla.Add(new Program("shubham", 1));
        blabla.Add(new Program("google", 3));
        blabla.Add(new Program("world",5));
        blabla.Add(new Program("hello", 5));
        blabla.Add(new Program("bye", 2));

berisi nama dan umur. Sekarang katakan kita ingin mencari nama dengan syarat Jadi saya akan gunakan,

    Predicate<Program> test = delegate (Program p) { return p.age > 3; };
        List<Program> matches = blabla.FindAll(test);
        Action<Program> print = Console.WriteLine;
        matches.ForEach(print);

mencoba Keep it Simple!

Shubham Khare
sumber