Func<>
là gì và nó được sử dụng để làm gì?Func là gì, như thế nào và khi nào nó được sử dụng
Trả lời
Func<T>
là loại đại biểu được xác định trước cho phương thức trả về một số giá trị thuộc loại T
.
Nói cách khác, bạn có thể sử dụng loại này để tham chiếu phương thức trả về một số giá trị là T
. Ví dụ.
public static string GetMessage() { return "Hello world"; }
có thể được tham chiếu như thế này
Func<string> f = GetMessage;
Nhưng nó cũng có thể đại diện cho một hàm đối số tĩnh =) –
@ Ark-kun không, điều đó không chính xác. Định nghĩa của 'Func
Không, tôi đúng. 'static int OneArgFunc (chuỗi này i) {return 42; } '' Func
Func<T1,R>
và được xác định trước generic Func
đại biểu khác (Func<T1,T2,R>
, Func<T1,T2,T3,R>
và những người khác) là đại biểu chung chung mà trả về kiểu của tham số chung cuối cùng.
Nếu bạn có hàm cần trả về các loại khác nhau, tùy thuộc vào thông số, bạn có thể sử dụng đại diện Func
, chỉ định loại trả về.
Hãy coi đó là trình giữ chỗ. Nó có thể khá hữu ích khi bạn có mã theo một mẫu nhất định nhưng không cần phải gắn với bất kỳ chức năng cụ thể nào. Ví dụ, xem xét phương pháp mở rộng Enumerable.Select
.
- Các mẫu là: cho tất cả các mục trong một chuỗi, chọn một số giá trị từ mục đó (ví dụ, một tài sản) và tạo ra một chuỗi mới gồm những giá trị này.
- Trình giữ chỗ là: một số hàm chọn thực sự nhận được các giá trị cho chuỗi được mô tả ở trên.
Phương pháp này mất Func<T, TResult>
thay vì bất kỳ chức năng cụ thể nào. Điều này cho phép nó được sử dụng trong bất kỳ ngữ cảnh nào khi áp dụng mẫu trên.
Ví dụ: giả sử tôi có số List<Person>
và tôi chỉ muốn tên của mọi người trong danh sách. Tôi có thể làm điều này:
var names = people.Select(p => p.Name);
Hoặc nói rằng tôi muốn tuổi của tất cả mọi người:
var ages = people.Select(p => p.Age);
Ngay lập tức, bạn có thể xem như thế nào tôi đã có thể tận dụng các mã cùng đại diện cho một mẫu (với Select
) với hai các chức năng khác nhau (p => p.Name
và p => p.Age
).
Cách khác là viết một phiên bản khác nhau Select
mỗi lần bạn muốn quét chuỗi cho một loại giá trị khác.Vì vậy, để đạt được hiệu quả tương tự như trên, tôi cần:
// Presumably, the code inside these two methods would look almost identical;
// the only difference would be the part that actually selects a value
// based on a Person.
var names = GetPersonNames(people);
var ages = GetPersonAges(people);
Với một đại biểu làm chỗ giữ chỗ, tôi tự do phải viết cùng một mẫu hoa văn trong những trường hợp như thế này.
Func<T1, T2, ..., Tn, Tr>
đại diện cho một hàm, có các đối số (T1, T2, ..., Tn) và trả về Tr.
Ví dụ, nếu bạn có một hàm:
double sqr(double x) { return x * x; }
Bạn có thể lưu nó như một số loại của một hàm biến:
Func<double, double> f1 = sqr;
Func<double, double> f2 = x => x * x;
Và sau đó sử dụng chính xác như bạn sẽ sử dụng sqr:
f1(2);
Console.WriteLine(f2(f1(4)));
, vv
Hãy nhớ rằng, đó là một đại biểu, để biết thêm thông tin nâng cao tham khảo tài liệu.
Câu trả lời Excelent, nhưng để biên dịch từ khóa tĩnh được neeed – boctulus
Nó chỉ là một đại biểu được xác định trước. Sử dụng nó, bạn không cần khai báo mọi đại biểu. Có một đại biểu được xác định trước khác, Action<T, T2...>
, tương tự nhưng trả về khoảng trống.
Tôi thấy Func rất hữu ích khi tạo thành phần cần được cá nhân hóa "khi đang di chuyển".
Lấy ví dụ rất đơn giản này: thành phần PrintListToConsole.
Một đối tượng rất đơn giản in danh sách đối tượng này vào bảng điều khiển. Bạn muốn cho nhà phát triển sử dụng nó để cá nhân hóa đầu ra.
Ví dụ: Bạn muốn cho phép anh ta xác định loại định dạng số dạng hạt và vân vân.
Without Func
Trước tiên, bạn phải tạo một giao diện cho một lớp học mà lấy đầu vào và tạo ra chuỗi in ra cửa sổ Console.
interface PrindListConsoleRender<T> {
String Render(T input);
}
Sau đó, bạn phải tạo lớp PrintListToConsole lấy giao diện đã tạo trước đó và sử dụng nó trên từng phần tử trong danh sách.
class PrintListToConsole<T> {
private PrindListConsoleRender<T> _renderer;
public void SetRenderer(PrindListConsoleRender<T> r) {
// this is the poin where I can personalize the render mechanism
_renderer = r;
}
public void PrintToConsole(List<T> list) {
foreach (var item in list) {
Console.Write(_renderer.Render(item));
}
}
}
Các nhà phát triển mà cần phải sử dụng thành phần của bạn phải:
1) thực hiện các giao diện
2) vượt qua các lớp thực sự cho PrintListToConsole
class myrenderer : PrindListConsoleRender<int> {
public String Render(int input) {
return "Number: " + input;
}
}
class Program {
static void Main(string[] args) {
var list = new List<int> { 1, 2, 3 };
var printer = new PrintListToConsole<int>();
printer.SetRenderer(new myrenderer());
printer.PrintToConsole(list);
string result = Console.ReadLine();
}
}
Sử dụng Func nó đơn giản hơn nhiều
Bên trong thành phần bạn định nghĩa một tham số có kiểu Func rằng đại diện cho một giao diện của một hàm mà phải mất một tham số đầu vào của loại T và trả về một chuỗi (đầu ra cho giao diện điều khiển)
class PrintListToConsole<T> {
private Func<T, String> _renderFunc;
public void SetRenderFunc(Func<T, String> r) {
// this is the point where I can set the render mechanism
_renderFunc = r;
}
public void StampaFunc(List<T> list) {
foreach (var item in list) {
Console.Write(_renderFunc(item));
}
}
}
Khi việc sử dụng nhà phát triển thành phần của bạn nó chỉ đơn giản là chuyển đến thành phần thực thi kiểu Func, đó là một hàm tạo đầu ra cho bàn điều khiển.
class Program {
static void Main(string[] args) {
var list = new Array[1, 2, 3];
var printer = new PrintListToConsole<int>();
printer.SetRenderFunc((o) => "Number:" + o);
string result = Console.ReadLine();
}
}
Func cho phép bạn xác định giao diện phương pháp chung khi đang di chuyển. Bạn xác định loại đầu vào là gì và loại đầu ra là gì. Đơn giản và súc tích.
Cảm ơn bạn đã đăng Marco này. Nó đã thực sự giúp tôi. Tôi đã cố gắng để hiểu func trong một thời gian và cũng tích cực sử dụng nó trong lập trình của tôi. Ví dụ này sẽ xóa đường dẫn. Tôi đã phải thêm phương thức StampaFunc như được bỏ qua trong mã ban đầu để ngăn nó hiển thị. –
- 1. GenericParameterHelper là gì và được sử dụng như thế nào?
- 2. C# - Thành phần là gì và nó thường được sử dụng như thế nào?
- 3. ViewState trong JSF là gì và nó được sử dụng như thế nào?
- 4. Biểu tượng SQL # có nghĩa là gì và nó được sử dụng như thế nào?
- 5. Dấu thời gian SSMA. Nó là gì, nó được sử dụng như thế nào?
- 6. [cmdletbinding()] là gì và nó hoạt động như thế nào?
- 7. Mạch ngắn là gì và nó được sử dụng như thế nào khi lập trình bằng Java?
- 8. Thẻ meta viewport được sử dụng như thế nào và nó hoạt động như thế nào?
- 9. Getattr() chính xác là gì và tôi sử dụng nó như thế nào?
- 10. Pyximport là gì và tôi nên sử dụng nó như thế nào?
- 11. Redis pubsub là gì và tôi sử dụng nó như thế nào?
- 12. Khi nào thuộc tính @JsonProperty được sử dụng và nó được sử dụng để làm gì?
- 13. Phương pháp Javascript CollectGarbage() là gì? Khi nào và tại sao nó nên được sử dụng?
- 14. Tệp IOR là gì, nó hoạt động như thế nào và nó hoạt động như thế nào?
- 15. "chế độ nghiêm ngặt" là gì và được sử dụng như thế nào?
- 16. C#: Sự kiện ảo là gì và chúng có thể được sử dụng như thế nào?
- 17. couchdb là gì, tôi nên sử dụng nó như thế nào?
- 18. Lớp hợp đồng là gì và được sử dụng như thế nào
- 19. Định tuyến phía máy khách là gì và được sử dụng như thế nào?
- 20. sharedUserId trong Android là gì và được sử dụng như thế nào?
- 21. Cụm từ thông dụng MM/DD/YYYY là gì và tôi sử dụng nó như thế nào trong php?
- 22. Một vùng tên là gì và nó được thực hiện như thế nào trong PHP?
- 23. Phương thức getView() được sử dụng như thế nào và nó được gọi ở đâu?
- 24. "Ném" làm gì và nó hữu ích như thế nào?
- 25. Ứng dụng CAD được viết là gì và chúng được sắp xếp như thế nào?
- 26. SELF JOIN là gì và khi nào bạn sẽ sử dụng nó?
- 27. io_service, tại sao và nó được sử dụng như thế nào?
- 28. ImmutableObjectAttribute được sử dụng như thế nào?
- 29. Request.InputStream là gì và khi nào nên sử dụng?
- 30. CATransform3DMakeRotation được sử dụng như thế nào?
Đó chỉ là lối tắt cho các đại biểu có chữ ký cụ thể. Để hiểu đầy đủ các câu trả lời dưới đây bạn sẽ cần phải hiểu các đại biểu ;-) –
Trong câu trả lời của @Oded nó nói 'Nếu bạn có một hàm cần trả về các kiểu khác nhau, tùy thuộc vào tham số, bạn có thể sử dụng một đại biểu Func, xác định kiểu trả về.' – Lijo