Helpex - Trao đổi & giúp đỡ Đăng nhập
34

Tôi không thể là người duy nhất cảm thấy mệt mỏi với việc xác định và đặt tên một người được ủy quyền chỉ cho một lệnh gọi đến một thứ gì đó yêu cầu một người được ủy quyền. Ví dụ: tôi muốn gọi .Refresh () trong một biểu mẫu có thể từ các chuỗi khác, vì vậy tôi đã viết mã này:

private void RefreshForm()
{
    if (InvokeRequired)
        Invoke(new InvokeDelegate(Refresh));
    else
        Refresh();
}

Tôi thậm chí không chắc mình phải làm như vậy, tôi chỉ đọc đủ để sợ rằng nó sẽ không hoạt động ở một số giai đoạn sau.
InvokeDelegate thực sự được khai báo trong một tệp khác, nhưng tôi có thực sự cần toàn bộ đại biểu chỉ dành riêng cho việc này không? không có bất kỳ đại biểu chung nào cả?
Ý tôi là, ví dụ, có một lớp Pen, nhưng cũng có Pens. tùy chọn bút để bạn không phải làm lại toàn bộ. Nó không giống nhau, nhưng tôi hy vọng bạn hiểu những gì tôi muốn nói.

34 hữu ích 2 bình luận 49k xem chia sẻ
52

Đúng. Trong .NET 3.5, bạn có thể sử dụng các đại biểu HàmHành động . Các đại biểu Func trả về một giá trị, trong khi các đại biểu Action trả về giá trị vô hiệu. Đây là tên loại sẽ trông như thế nào:

System.Func<TReturn> // (no arg, with return value)
System.Func<T, TReturn> // (1 arg, with return value)
System.Func<T1, T2, TReturn> // (2 arg, with return value)
System.Func<T1, T2, T3, TReturn> // (3 arg, with return value)
System.Func<T1, T2, T3, T4, TReturn> // (4 arg, with return value)

System.Action // (no arg, no return value)
System.Action<T> // (1 arg, no return value)
System.Action<T1, T2> // (2 arg, no return value)
System.Action<T1, T2, T3> // (3 arg, no return value)
System.Action<T1, T2, T3, T4> // (4 arg, no return value)

Tôi không biết tại sao họ dừng lại ở 4 args mỗi người, nhưng nó luôn là đủ đối với tôi.

52 hữu ích 3 bình luận chia sẻ
26

Có đại biểu Hành động mà bạn có thể sử dụng, như sau:

private void RefreshForm()
{
    if (InvokeRequired) Invoke(new Action(Refresh));
    else Refresh();
}

Hoặc, với cú pháp lambda:

private void RefreshForm()
{
    if (InvokeRequired) Invoke((Action)(() => Refresh()));
    else Refresh();
}

Cuối cùng, có cú pháp đại biểu ẩn danh:

private void RefreshForm()
{
    if (InvokeRequired) Invoke((Action)(delegate { Refresh(); }));
    else Refresh();
}
26 hữu ích 5 bình luận chia sẻ
8

Trong trường hợp cụ thể này, bạn có thể (và nên) chỉ sử dụng MethodInvoker để làm điều này ... đó là lý do tại sao nó tồn tại.

if (InvokeRequired)
    Invoke(new MethodInvoker(Refresh));
else
    Refresh();

Nếu bạn đang làm việc khác mà bạn có thể, như những người khác đã trả lời, hãy sử dụng Func <T, ...> hoặc Action <T, ...> nếu chúng phù hợp với trường hợp sử dụng của bạn.

8 hữu ích 1 bình luận chia sẻ
5

Phiên bản ngắn:

Invoke((MethodInvoker)delegate { Refresh(); });

Sau đó, bạn cũng có thể bỏ séc của InvokeRequired; bạn chỉ có thể gọi nó như nó vốn có. Cũng hoạt động nếu bạn cần truyền tham số, vì vậy không cần các đại biểu cụ thể cho tham số khác (cũng hoạt động tốt với đại biểu Hành động ít tham số):

private void SetControlText(Control ctl, string text)
{
    Invoke((MethodInvoker)delegate { ctl.Text = text; });
}
5 hữu ích 5 bình luận chia sẻ
2

Tôi có thực sự cần toàn bộ một đại biểu dành riêng cho việc này không? không có bất kỳ đại biểu chung nào cả?

Việc xác định các đại diện của riêng bạn thực sự có thể giúp gỡ lỗi dễ dàng hơn, nếu chỉ vì Intellisense có thể cho bạn biết tên của các tham số của bạn. Ví dụ, bạn viết một ủy nhiệm như thế này:

public delegate int UpdateDelegate(int userID, string city, string, state, string zip);

Khi bạn sử dụng mã, .NET sẽ thông báo cho bạn về tên tham số, tên đại biểu, v.v., do đó, có rất nhiều ngữ cảnh ngay trong định nghĩa đại biểu nếu bạn không chắc chắn chính xác cách nào đó được sử dụng.

Tuy nhiên, nếu bạn không ngại hy sinh Intellisense, thì đã có một lớp đại biểu được xác định trong không gian tên Hệ thống có thể được sử dụng làm đại biểu đặc biệt:

Func<T>
Func<T, U>
Func<T, U, V>
Func<T, U, V, W>
Action, Action<T>
Action<T, U>
Action<T, U, V>
Action<T, U, V, W>

Chỉ ActionActiontồn tại trong .NET 2.0, nhưng nó đủ dễ dàng để khai báo một lớp trợ giúp với các đại biểu còn lại mà bạn cần cho các loại chức năng đặc biệt linh tinh này.

2 hữu ích 0 bình luận chia sẻ
1

Có, có những đại biểu chung chung. Action<T1, T2...>là một đại biểu chung nhận một số tham số và không trả về giá trị nào và Func<T1, T2...R>là một đại biểu chung chung nhận một số tham số và trả về một giá trị.

1 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ c# delegates anonymous-methods , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading