Func <T> () so với Func <T> .Invoke ()


82

Tôi tò mò về sự khác biệt giữa việc gọi một Func trực tiếp và sử dụng Invoke () trên đó. Có sự khác biệt? Có phải là đường đầu tiên, theo cú pháp và gọi Invoke () bên dưới không?

public T DoWork<T>(Func<T> method)
{
    return (T)method.Invoke();
}

vs

public T DoWork<T>(Func<T> method)
{
    return (T)method();
}

Hay tôi đang đi sai hướng hoàn toàn :) Cảm ơn.


Câu trả lời:


111

Không có sự khác biệt nào cả. Thứ hai chỉ là cách viết tắt của Invoke, được cung cấp bởi trình biên dịch. Chúng biên dịch sang cùng một IL.


1
Việc tắt phương thức Invoke () sẽ dẫn đến lỗi trình biên dịch: "Không thể chuyển đổi hoàn toàn kiểu 'System.Func <T>' thành 'T'". Tôi đang biên soạn chống NET 4.
Mike

2
@Mike: Điều đó sẽ xảy ra nếu bạn cũng bỏ qua dấu ngoặc - tức là đã cố gắng quay lại (T)methodchứ không phải (T)method().
Jon Skeet

@JonSkeet Vậy có phải anh chàng này sai ở đây không: social.msdn.microsoft.com/Forums/en-US/…
superlogical 12/1213

4
@superlogical: Có hai vấn đề ở đây. Thứ nhất, câu hỏi đặt ra là về sự khác biệt giữa việc gọi một phương thức trực tiếp và gọi nó thông qua một đại biểu. Điều đó không giống như sự khác biệt giữa foo()foo.Invoke()đâu foolà một biến của kiểu đại biểu. Vấn đề khác là câu trả lời dường như đang nói đến Control.Invoke, điều này không giống như việc kêu gọi Invokemột đại biểu.
Jon Skeet

2
@LucaCremonesi: Nếu đó là kết quả của một cuộc gọi phương thức, tôi thường thích Invoke, vì nó GetAction()()trông kỳ lạ, nhưng có GetAction().Invoke()vẻ ổn. Nhưng tôi không bận tâm về cả hai cách, phần lớn.
Jon Skeet

17

Invoke hoạt động tốt với toán tử lan truyền rỗng C # 6 mới, bây giờ bạn có thể làm

T result = method?.Invoke();

thay vì

T result = method != null ? method() : null;

Bạn có thể minh họa một tình huống mà điều này hữu ích không? Trường hợp sách giáo khoa đang nêu ra các sự kiện.
Gusdor

1
Ví dụ, bạn có thể có một tham số Func tùy chọn mà nếu không có giá trị nào được gán, thì giá trị mặc định (Func) là null và bị bỏ qua.
Austin Salgat

1
Đó là trường hợp phổ biến đối với các sự kiện và các đại biểu nhiều lớp khác - chúng thường được khởi tạo bằng null và nhận được giá trị không phải null sau khi gọi +=. Vì vậy, nếu bạn sắp tổ chức một sự kiện và không biết liệu có bất kỳ đăng ký nào hay không, giải pháp ngắn gọn là gọi điện ?.Invoke(...).
stop-cran,
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.