System.Linq.Enumerable.OfType<T> - is there a F# way?

送分小仙女□ 提交于 2021-02-08 05:39:15

问题


I'm looking to use the F# WSDL Type Provider. To call the web service I am using, I need to attach my client credentials to the System.ServiceModel.Description.ClientCredentials.

This is the C# code I have:

var serviceClient = new InvestmentServiceV1Client.InvestmentServiceV1Client();

foreach (ClientCredentials behaviour in serviceClient.Endpoint.Behaviors.OfType<ClientCredentials>())
{
    (behaviour).UserName.UserName = USERNAME;
    (behaviour).UserName.Password = PASSWORD;
    break;
}

This is the F# code I have so far:

let client = new service.ServiceTypes.InvestmentServiceV1Client()
let xxx = client.Endpoint.Behaviors
|> Seq.choose (fun p -> 
    match box p with   
    :?   System.ServiceModel.Description.ClientCredentials as x -> Some(x) 
    _ -> None) 
|> (System.ServiceModel.Description.ClientCredentials)p.UserName.UserName = USERNAME

Is there an F# equivalent of System.Linq.Enumerable.OfType<T> or should I just use raw OfType<T> ?


回答1:


I suppose the question is mainly about the break construct, which is not available in F#. Well, the code really just sets the user name and password for the first element of the collection (or none, if the collection is empty). This can be done easily using pattern matching, if you turn the collection to an F# list:

// Get behaviours as in C# and convert them to list using 'List.ofSeq'
let sc = new InvestmentServiceV1Client.InvestmentServiceV1Client()
let behaviours = sc.Endpoint.Behaviors.OfType<ClientCredentials>() |> List.ofSeq

// Now we can use pattern matching to see if there is something in the list
match behaviours with
| behaviour::_ ->
    // And if the list is non-empty, set the user name and password
    behaviour.UserName.UserName <- USERNAME
    behaviour.UserName.Password <- PASSWORD
| _ -> ()



回答2:


I think you've already implemented the F# equivalent of .OfType(). For emulating the break statement you can do as Tomas does in his answer (matching on list), or you call Seq.head (throws if there are no elements left), or you can do this:

let xxx = 
    client.Endpoint.Behaviors
    |> Seq.choose (function
        | :? System.ServiceModel.Description.ClientCredentials as x -> Some x
        | _ -> None ) 
    |> Seq.tryPick Some

match xxx with
| Some behavior -> ... // First element of required type found
| None -> ...          // No elements of required type at all in sequence


来源:https://stackoverflow.com/questions/19353818/system-linq-enumerable-oftypet-is-there-a-f-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!