Gần đây tôi đã xem F #, và mặc dù tôi không thể nhảy qua hàng rào bất cứ lúc nào, nó chắc chắn làm nổi bật một số khu vực mà C# (hoặc hỗ trợ thư viện) có thể làm cho cuộc sống dễ dàng hơn.switch/pattern matching idea
Cụ thể, tôi đang suy nghĩ về khả năng khớp mẫu của F #, cho phép cú pháp rất phong phú - nhiều biểu cảm hơn so với chuyển đổi hiện tại/điều kiện C# tương đương có điều kiện. Tôi sẽ không cố gắng đưa ra một ví dụ trực tiếp (F # của tôi không phải là nó), nhưng trong ngắn hạn nó cho phép:
- khớp với loại (với kiểm tra đầy đủ cho các công đoàn bị phân biệt đối xử) suy luận kiểu cho biến ràng buộc, cho phép truy cập thành viên vv]
- trận đấu bởi vị
- kết hợp của các bên trên (và có thể một số kịch bản khác tôi không biết)
trong khi nó sẽ là đáng yêu để C# cuối cùng mượn [ahem] một số sự phong phú này, trong thời gian đó tôi đã xem xét những gì có thể được thực hiện t runtime - ví dụ, nó là khá dễ dàng để gõ cùng một số đối tượng để cho phép:
var getRentPrice = new Switch<Vehicle, int>()
.Case<Motorcycle>(bike => 100 + bike.Cylinders * 10) // "bike" here is typed as Motorcycle
.Case<Bicycle>(30) // returns a constant
.Case<Car>(car => car.EngineType == EngineType.Diesel, car => 220 + car.Doors * 20)
.Case<Car>(car => car.EngineType == EngineType.Gasoline, car => 200 + car.Doors * 20)
.ElseThrow(); // or could use a Default(...) terminator
nơi getRentPrice là một xe Func <, int >.
[note - có thể chuyển/trường hợp ở đây là các điều khoản sai ... nhưng nó cho thấy những ý tưởng]
Đối với tôi, đây là rõ ràng hơn rất nhiều so với tương đương bằng cách sử dụng lặp đi lặp lại nếu/khác, hoặc một ternary composit có điều kiện (được rất lộn xộn cho các biểu thức không tầm thường - dấu ngoặc đơn). Nó cũng tránh được lô khi truyền và cho phép tiện ích mở rộng đơn giản (trực tiếp hoặc thông qua các phương thức mở rộng) cho các kết quả cụ thể hơn, ví dụ: so khớp InRange (...) có thể so sánh với VB ... Trường hợp "x Để y "sử dụng.
Tôi chỉ đang cố gắng đánh giá liệu mọi người có nghĩ rằng có nhiều lợi ích từ các cấu trúc như trên (trong trường hợp không hỗ trợ ngôn ngữ) không?
Lưu ý thêm rằng tôi đã chơi với 3 biến thể của trên:
- một Func < TSource, TValue > phiên bản để đánh giá - so sánh với báo cáo có điều kiện ternary composit
- một hành động <TSource> phiên bản - có thể so sánh nếu/else nếu/else nếu/else if/else
- biểu thức < Func < TSource, TValue > > phiên bản - là phiên bản đầu tiên, nhưng có thể sử dụng bởi các nhà cung cấp LINQ tùy ý
Ngoài ra, sử dụng phiên bản Expression cho phép biểu hiện lại cây biểu thị, thay vì sử dụng lặp đi lặp lại yêu cầu. Tôi đã không kiểm tra gần đây, nhưng trong một số ban đầu Entity Framework xây dựng tôi dường như nhớ lại điều này là cần thiết, vì nó không giống như InvocationExpression rất nhiều. Nó cũng cho phép sử dụng hiệu quả hơn với LINQ-to-Objects, vì nó tránh lặp lại các cuộc gọi đại biểu - các thử nghiệm cho thấy một kết quả giống như trên (sử dụng biểu thức biểu thức) thực hiện ở cùng tốc độ [nhanh hơn, thực tế] so với C# tương đương câu lệnh điều kiện tổng hợp.Để hoàn thành, Func <...> dựa trên phiên bản mất 4 lần miễn là câu lệnh điều kiện C#, nhưng vẫn còn rất nhanh và không có khả năng là một nút cổ chai lớn trong hầu hết các trường hợp sử dụng.
Tôi hoan nghênh mọi suy nghĩ/đầu vào/phê bình/v.v. ở trên (hoặc về khả năng hỗ trợ ngôn ngữ C# phong phú hơn ... đây là hy vọng ;-p).
Bạn có thể sử dụng VB .NET hỗ trợ điều này trong tuyên bố trường hợp chọn. Eek! –
Tôi thích ý tưởng này và nó làm cho một hình thức rất đẹp và linh hoạt hơn của một trường hợp chuyển đổi; Tuy nhiên, đây không phải là cách thực sự được tôn tạo của việc sử dụng cú pháp giống như LINQ như một trình bao bọc if-then? Tôi sẽ không khuyến khích ai đó sử dụng điều này thay cho thỏa thuận thực sự, tức là tuyên bố 'chuyển đổi trường hợp '. Đừng làm cho tôi sai, tôi nghĩ rằng nó có vị trí của nó và tôi có lẽ sẽ tìm cách để thực hiện. – IAbstract
Nếu bạn viết một cái gì đó nhiều hơn một hello-world với các mẫu hoạt động (F # 3.0), tôi nghĩ, điều đó sẽ đẩy bạn qua các cạnh ... –