ฉันได้ดู F # เมื่อเร็ว ๆ นี้และในขณะที่ฉันไม่ได้กระโดดข้ามรั้วในไม่ช้ามันก็ไฮไลท์บางพื้นที่ที่ C # (หรือการสนับสนุนห้องสมุด) จะทำให้ชีวิตง่ายขึ้น
โดยเฉพาะอย่างยิ่งฉันกำลังคิดเกี่ยวกับความสามารถในการจับคู่รูปแบบของ F # ซึ่งอนุญาตให้ใช้ไวยากรณ์ที่หลากหลายมากซึ่งแสดงออกได้ดีกว่าสวิตช์ C / เงื่อนไขที่เทียบเท่าในปัจจุบัน ฉันจะไม่พยายามยกตัวอย่างโดยตรง (F # ของฉันไม่ได้ขึ้นอยู่กับมัน) แต่ในระยะสั้นจะช่วยให้:
- จับคู่ตามประเภท (พร้อมการตรวจสอบที่ครอบคลุมอย่างสมบูรณ์สำหรับสหภาพที่มีการแบ่งแยก) [หมายเหตุสิ่งนี้ยังทำให้ประเภทของตัวแปรที่ถูกผูกไว้ให้การเข้าถึงสมาชิก ฯลฯ ]
- จับคู่โดยภาคแสดง
- การรวมกันของด้านบน (และอาจเป็นไปได้ว่าบางสถานการณ์อื่น ๆ ที่ฉันไม่ทราบ)
ในขณะที่มันน่ารักสำหรับ C # ในที่สุดก็ยืม [ahem] ความร่ำรวยบางอย่างในระหว่างนี้ฉันได้ดูสิ่งที่สามารถทำได้ในรันไทม์ - ตัวอย่างเช่นมันค่อนข้างง่ายที่จะรวมวัตถุบางอย่างเข้าด้วยกัน:
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
โดยที่ getRentPrice คือ Func <Vehicle, int>
[หมายเหตุ - อาจจะเปลี่ยน / กรณีที่นี่เป็นคำที่ผิด ... แต่มันแสดงให้เห็นความคิด]
สำหรับฉันมันชัดเจนกว่าการใช้ซ้ำถ้า / / หรือคอมโพสิตเงื่อนไขที่ประกอบไปด้วยสาม (ซึ่งได้รับยุ่งมากสำหรับการแสดงออกที่ไม่น่าสนใจ - วงเล็บมากมาย) นอกจากนี้ยังหลีกเลี่ยงจำนวนมากของการหล่อและช่วยให้การขยายง่าย (ทั้งโดยตรงหรือผ่านทางวิธีการขยาย) เพื่อการแข่งขันมากขึ้นเฉพาะสำหรับตัวอย่าง inrange ( ... ) ตรงกับเปรียบได้กับ VB เลือก ... กรณี "X เป็น Y "การใช้งาน
ฉันแค่พยายามที่จะวัดว่าผู้คนคิดว่ามีประโยชน์มากจากการสร้างดังกล่าวข้างต้น (ในกรณีที่ไม่มีการสนับสนุนภาษา)
โปรดทราบว่าฉันได้เล่นกับ 3 ตัวแปรข้างต้น:
- เวอร์ชัน Func <TSource, TValue> สำหรับการประเมิน - เปรียบเทียบได้กับคำสั่งเงื่อนไขประกอบไปด้วยสามส่วน
- เวอร์ชัน Action <TSource> เปรียบเทียบได้กับ if / else if / else if / else if / else
- Expression <Func <TSource, TValue >> version - เป็นรุ่นแรก แต่ใช้ได้โดยผู้ให้บริการ LINQ ตามอำเภอใจ
นอกจากนี้การใช้เวอร์ชันที่อิงกับ Expression จะช่วยให้สามารถเขียนใหม่ Expression-tree ได้โดยการฝังสาขาทั้งหมดลงใน Expression แบบมีเงื่อนไขแบบคอมโพสิตแทนที่จะใช้การเรียกซ้ำ ฉันไม่ได้ตรวจสอบเมื่อเร็ว ๆ นี้ แต่ใน Entity Framework รุ่นก่อน ๆ บางรุ่นนั้นดูเหมือนว่าฉันจำได้ว่ามันจำเป็นเพราะไม่ชอบ Invocation Expression มาก นอกจากนี้ยังช่วยให้การใช้งานที่มีประสิทธิภาพยิ่งขึ้นด้วย LINQ-to-Objects เนื่องจากจะหลีกเลี่ยงการมอบหมายตัวแทนซ้ำ - การทดสอบแสดงการจับคู่เหมือนด้านบน (โดยใช้แบบฟอร์ม Expression) ดำเนินการที่ความเร็วเดียวกัน คำสั่งเงื่อนไขแบบรวม เพื่อความสมบูรณ์ Func <... > เวอร์ชั่นที่ใช้นั้นใช้เวลานานกว่าคำสั่งเงื่อนไข C # ถึง 4 เท่า แต่ยังเร็วมากและไม่น่าจะเป็นปัญหาคอขวดที่สำคัญในกรณีใช้งานส่วนใหญ่
ฉันยินดีต้อนรับความคิดใด ๆ / การป้อนข้อมูล / การวิจารณ์ / ฯลฯ ที่ด้านบน (หรือในความเป็นไปได้ของการสนับสนุนภาษา C # ยิ่งขึ้น ... นี่คือความหวัง ;-p)
switch-case
คำสั่ง อย่าเข้าใจฉันผิดฉันคิดว่ามันมีสถานที่และฉันอาจจะมองหาวิธีที่จะใช้