如何在使用.NET Custom Collection对象时编写功能代码

Kno*_*uch 1 sharepoint f#

我正在尝试使用F#使用SharePoint 2010对象(就像经验一样).

所以我写了这段代码

let getSPDomainUsers (spWeb : SPWeb) =
seq {
  for r in spWeb.RoleAssignments do
    match r.Member with
    | :? SPUser as user ->        
      for b in r.RoleDefinitionBindings do
        if (user.IsDomainGroup) then yield (spWeb.Url.ToLower(), user, b.Name.ToLower())
    | :? SPGroup as group ->
      for u in group.Users do
        for b in r.RoleDefinitionBindings do
          if (u.IsDomainGroup) then yield (spWeb.Url.ToLower(), u, b.Name.ToLower())
    | _ -> ()
} 
Run Code Online (Sandbox Code Playgroud)

然而,所有这些for循环和条件我的代码看起来非常必要.

而不是for循环我想做像List.map这样的事情然而大多数像RoleDefinitionBindings或RoleAssignments这样的对象都返回我不是列表或数组或序列的集合所以我被迫写循环.

当返回类型是自定义集合对象(如SPRoleAssignmentCollection和SPRoleDefinitionBindingCollection)时,您能告诉我一种可以避免循环的方法吗?

Jac*_* P. 5

SPRoleDefinitionBindingCollection继承SPBaseCollection哪个实现IEnumerable(但不是IEnumerable<T>,即seq<'T>).您可以使用Seq.cast将实例IEnumerable转换为seq<'T>.

一旦你有了,seq<'T>你可以使用F#Seq模块中的常用功能.

这是代码的清理版本.我没有SharePoint所以我无法编译/测试它; 您可能需要在将IEnumerable它们输入之前显式地转换自定义集合类型Seq.cast.

let userInfo (user : SPUser) =
    user.RoleDefinitionBindings
    |> Seq.cast<SPRoleDefinition>
    |> Seq.choose (fun b ->
        if user.IsDomainGroup then
            Some (spWeb.Url.ToLower(), user, b.Name.ToLower())
        else None)

let getSPDomainUsers (spWeb : SPWeb) =
    spWeb.RoleAssignments
    |> Seq.cast<SPRoleAssignment>
    |> Seq.collect (fun r ->
        match r.Member with
        | :? SPUser as user ->
            userInfo user
        | :? SPGroup as group ->
            Seq.collect userInfo group.Users
        | _ ->
            Seq.empty)
Run Code Online (Sandbox Code Playgroud)