[英]f# pattern match on c# classes
我有一個C#模塊接收和處理Operation類的各種實例。 接口聲明了一個方法:
Operation Transform(Operation o1, Operation o2);
但是有幾種操作。 例如,對於簡單的文本編輯,有InsertOperation和DeleteOperation,因此Transform方法的主體首先排序它接收的操作類型並將其轉換。 在學習了一些F#后,我想在其中重寫項目的這一部分(作為練習和實驗)並且認為我可以通過這樣的模式匹配來更好地處理這個:
let Transform (oa: Operation) (ob: Operation) =
match oa, ob with
| InsertOperation o1, InsertOperation o2 -> //transformation
| DeleteOperation o1, InsertOperation o2 -> //transformation
| InsertOperation o1, DeleteOperation o2 -> //transformation
| DeleteOperation o1, DeleteOperation o2 -> //transformation
但是,我收到以下錯誤消息:
The pattern discriminator 'InsertOperation' is not defined
Operation類及其后代是用C#編寫的,但我認為這不應該成為問題。 有人可以解釋為什么這是一個問題,我怎么能解決這個問題?
由於這不是一個有區別的聯合,而只是一組類(用C#編寫),你需要使用一個類型測試模式 :
let Transform (oa: Operation) (ob: Operation) =
match oa, ob with
| (:? InsertOperation as o1), (:? InsertOperation as o2) -> //transformation
| (:? DeleteOperation as o1), (:? InsertOperation as o2) -> //transformation
| (:? InsertOperation as o1), (:? DeleteOperation as o2) -> //transformation
| (:? DeleteOperation as o1), (:? DeleteOperation as o2) -> //transformation
有關詳細信息,請參閱模式匹配中的類型測試模式。
另一個答案建議在Transform
函數中對類型進行直接匹配,這是一個很好的解決方案。 如果為您的案例定義一個自定義活動模式 ,您可以分解一些樣板,特別是因為它聽起來您將多次與Operation
類型匹配。
let (|Insert|Delete|Unknown|) (oper: Operation) =
match oper with
| :? InsertOperation as iop -> Insert iop
| :? DeleteOperation as dop -> Delete dop
| _ -> Unknown // catches other subtypes of Operation you don't know about yet.
然后你可以像這樣使用它:
let transform (oa: Operation) (ob: Operation) =
match oa, ob with
| Insert oa, Insert ob -> ...
| Delete oa, Insert ob -> ...
...
| Unknown, _ | _, Unknown -> ...
這為您提供了與區分聯合幾乎相同的語法,但更重要的是,讓您將操作視為模式匹配的閉合類型。 例如,您將獲得有關您未處理的案例的正確警告,而不是通用的“其他子類型”警告。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.