Gần đây tôi đã xem xét F # và trong khi tôi không có khả năng sớm vượt qua hàng rào, nó chắc chắn làm nổi bật một số lĩnh vực mà C # (hoặc hỗ trợ thư viện) có thể giúp cuộc sống dễ dàng hơn.
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ú - biểu cảm hơn nhiều so với tương đương C # chuyển đổi / điều kiện hiện tại. Tôi sẽ không thử đưa ra một ví dụ trực tiếp (F # của tôi không phù hợp với nó), nhưng tóm lại, nó cho phép:
- khớp theo loại (với kiểm tra phạm vi bảo hiểm đầy đủ cho các hiệp hội bị phân biệt đối xử) [lưu ý điều này cũng tạo ra loại cho biến bị ràng buộc, cho phép truy cập thành viên, v.v.]
- phù hợp với vị ngữ
- kết hợp của những điều trên (và có thể một số tình huống khác mà tôi không biết)
Mặc dù thật đáng yêu khi C # cuối cùng đã mượn [ahem] một số sự phong phú này, nhưng trong thời gian tạm thời tôi đã xem xét những gì có thể được thực hiện trong thời gian chạy - ví dụ, khá dễ dàng để kết hợp 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
trong đó getRentprice là Func <Xe, int>.
[lưu ý - có thể Switch / Case ở đây là thuật ngữ sai ... nhưng nó cho thấy ý tưởng]
Đối với tôi, điều này rõ ràng hơn nhiều so với việc sử dụng lặp lại if / other hoặc điều kiện ternary hỗn hợp (điều này rất lộn xộn cho các biểu thức không tầm thường - ngoặc galore). Nó cũng tránh được nhiều lần truyền và cho phép 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ả khớp cụ thể hơn, ví dụ: khớp InRange (...) có thể so sánh với VB Chọn ... Case "x To y " sử dụng.
Tôi chỉ đang cố gắng đánh giá xem mọi người có nghĩ rằng có nhiều lợi ích từ các cấu trúc như trên không (trong trường hợp không có hỗ trợ ngôn ngữ)?
Ngoài ra, xin lưu ý rằng tôi đã chơi với 3 biến thể ở trên:
- một phiên bản Func <TSource, TValue> để đánh giá - có thể so sánh với các câu lệnh điều kiện ternary tổng hợp
- phiên bản Hành động <TSource> - có thể so sánh với if / other if / other if / other if / other
- một phiên bản <Func <TSource, TValue >> - là phiên bản đầu tiên, nhưng có thể sử dụng được bởi các nhà cung cấp LINQ tùy ý
Ngoài ra, sử dụng phiên bản dựa trên Biểu thức cho phép viết lại cây Biểu thức, về cơ bản nội tuyến tất cả các nhánh thành Biểu thức điều kiện tổng hợp duy nhất, thay vì sử dụng lệnh gọi lặp lại. Gần đây tôi đã không kiểm tra, nhưng trong một số bản dựng Entity Framework đầu tiên, 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-Object, vì nó tránh được các lệnh ủy nhiệm lặp đi lặp lại - các thử nghiệm cho thấy một trận đấu 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 một chút so với C # tương đương tuyên bố điều kiện tổng hợp. Để hoàn thiện, phiên bản dựa trên Func <...> mất 4 lần so với tuyên bố điều kiện C #, nhưng vẫn rất nhanh và không chắc 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 bất kỳ suy nghĩ / đầu vào / phê bình / vv nào ở trên (hoặc về khả năng hỗ trợ ngôn ngữ C # phong phú hơn ... đây là hy vọng ;-p).
switch-case
tuyên bố. Đừng hiểu sai ý tôi, tôi nghĩ nó có chỗ đứng và có lẽ tôi sẽ tìm cách để thực hiện.