Đại biểu dự đoán trong C #


256

Bạn có thể giải thích cho tôi không:

  • Một đại biểu dự đoán là gì?
  • Chúng ta nên sử dụng vị ngữ ở đâu?
  • Bất kỳ thực hành tốt nhất khi sử dụng vị ngữ?

Mã nguồn mô tả sẽ được đánh giá cao.

Câu trả lời:


319

Một vị ngữ là một hàm trả về truehoặc false. Một đại biểu vị ngữ là một tham chiếu đến một vị ngữ.

Vì vậy, về cơ bản một đại biểu vị ngữ là một tham chiếu đến một hàm trả về truehoặc false. Vị ngữ rất hữu ích để lọc danh sách các giá trị - đây là một ví dụ.

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

Bây giờ nếu bạn đang sử dụng C # 3, bạn có thể sử dụng lambda để thể hiện vị ngữ theo cách sạch hơn:

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: trong đoạn mã đầu tiên của bạn, có nên yeild returnthay thế không? Hoặc làm thế nào nó hoạt động, làm thế nào nó lặp đi lặp lại trên toàn bộ danh sách?
VoodooChild

5
@VoodooChild: Hãy nhớ rằng vị ngữ sẽ được gọi lần lượt cho từng phần tử trong chuỗi . Vì vậy, greaterThanTworeturnkhông yield returnvì nó là FindAllphương pháp mà là xử lý các chuỗi cho bạn.
Andrew Hare

1
@AndrewHare, có thể có i > val, thay vì i > 2, valgiá trị được nhập bởi người dùng.
Mourya

81

Dẫn đầu từ câu trả lời của Andrew liên quan đến c # 2 và c # 3 ... bạn cũng có thể thực hiện chúng theo dòng cho một chức năng tìm kiếm tắt (xem bên dưới).

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;
                           });
    }
}

Hi vọng điêu nay co ich.


11

Chỉ cần một đại biểu trả về một boolean. Nó được sử dụng rất nhiều trong danh sách lọc nhưng có thể được sử dụng bất cứ nơi nào bạn muốn.

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

9

Có một bài viết hay về các vị từ ở đây , mặc dù nó có từ thời .NET2, vì vậy không có đề cập đến các biểu thức lambda trong đó.


Liên kết trong câu trả lời của bạn không còn liên kết đến một bài viết thực tế
David Cram

@David Cram: Cảm ơn, tôi đã cập nhật liên kết để sử dụng Wayback Machine, mặc dù bài viết này hiện đang thực sự lỗi thời.
LukeH

6

Đại biểu dự đoán là gì?

1) Vị ngữ là một tính năng trả về đúng hoặc sai. Khái niệm này đã xuất hiện trong khung .net 2.0. 2) Nó đang được sử dụng với biểu thức lambda (=>). Nó có loại chung chung như là một đối số. 3) Nó cho phép một hàm vị ngữ được xác định và chuyển làm tham số cho hàm khác. 4) Đây là trường hợp đặc biệt của a Func, trong đó chỉ cần một tham số duy nhất và luôn trả về một bool.

Trong không gian tên C #:

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

Nó được định nghĩa trong không gian tên hệ thống.

Chúng ta nên sử dụng Đại biểu dự phòng ở đâu?

Chúng ta nên sử dụng Đại biểu dự đoán trong các trường hợp sau:

1) Để tìm kiếm các mục trong một bộ sưu tập chung. ví dụ

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

2) Ví dụ cơ bản rút ngắn mã và trả về đúng hoặc sai:

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

Bây giờ, Gọi vị ngữ trên:

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

3) Một phương thức ẩn danh cũng có thể được gán cho loại đại biểu Dự đoán như sau:

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

Bất kỳ thực hành tốt nhất về vị ngữ?

Sử dụng Func, Lambda Expressions và Delegates thay vì Pratesates.


5

Các phương thức tìm kiếm dựa trên vị ngữ cho phép một biểu thức ủy nhiệm hoặc biểu thức lambda quyết định xem một phần tử đã cho có phải là một trận đấu hay không. Một vị ngữ chỉ đơn giản là một đại biểu chấp nhận một đối tượng và trả về đúng hoặc sai: đại biểu công khai bool Dự đoán (đối tượng 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"); }

2

Nếu bạn đang ở VB 9 (VS2008), một vị từ có thể là một hàm phức tạp:

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

Hoặc bạn có thể viết vị ngữ của mình dưới dạng lambda, miễn là nó chỉ có một biểu thức:

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

0

Vị ngữ nằm trong danh mục đại biểu chung trong C #. Điều này được gọi với một đối số và luôn trả về kiểu boolean. Về cơ bản, vị ngữ được sử dụng để kiểm tra điều kiện - đúng / sai. Nhiều lớp hỗ trợ vị ngữ như một đối số. Ví dụ: list.findall mong đợi vị từ tham số. Dưới đây là một ví dụ về vị ngữ.

Tưởng tượng một con trỏ hàm với chữ ký -

bool ủy nhiệm myDelegate (T khớp);

Đây là ví dụ

Nút.cs

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

Lớp chính -

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();
        }
    }
}

0

Đơn giản -> họ cung cấp các giá trị Đúng / Sai dựa trên điều kiện chủ yếu được sử dụng để truy vấn. chủ yếu được sử dụng với các đại biểu

xem xét ví dụ về danh sách

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

chứa tên và tuổi. Bây giờ nói rằng chúng tôi muốn tìm tên với điều kiện Vì vậy tôi sẽ sử dụng,

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

đã cố gắng để giữ cho nó đơn giản!


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.