簡體   English   中英

f#模式匹配c#類

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM