1

我有这个代码

let inline ProcessExpendableADGroups (input : ('a * SPUser) seq) =
  input
  |> Seq.filter (fun (_, u : SPUser) -> u.IsDomainGroup = true)       
  |> Seq.filter (fun (_, u : SPUser) -> ADUtility.IsADGroupExpandable u.LoginName = true)      
  |> List.ofSeq
  |> List.iter( 
      fun ( li : 'a, u : SPUser) -> 
        let userList = ADUtility.GetUsers u.LoginName 
        if (Seq.length userList <= 500) then
          userList
          |> Seq.filter (fun l -> InfobarrierPolicy.IsUserInPolicy l "FW" = true) 
          |> Seq.iter (
              fun ln ->
                let x = ADUtility.GetNameAndEmail ln 
                let (email, name) = x.Value
                SPUtility.CopyRoleAssignment li u.LoginName ln email name
                li.Update()
              )
          SPUtility.RemoveRoleAssignment li u
      )      

list3 
|> List.iter (
    fun w -> 
      SPUtility.GetDirectAssignmentsforListItems w |> ProcessExpendableADGroups
      SPUtility.GetDirectAssignmentsforFolders w |> ProcessExpendableADGroups
      SPUtility.GetDirectAssignmentsforLists w |> ProcessExpendableADGroups
      SPUtility.GetDirectAssignmentsforWeb w |> ProcessExpendableADGroups
   )

这里 GetDirectAssignmentsforListItems 方法返回一个元组序列 (SPListItem * SPUser) GetDirectAssignmentsforWeb 返回一个元组序列 (SPWeb * SPUser)。

我需要将此序列发送到一个函数,该函数对这些项目进行非常相似的处理,除了最后我必须在这些项目上调用一个名为“更新”的方法。

我已经编写了一个带有通用参数的方法,但是当我在通用参数上调用 Update 时遇到了问题。

我不能限制这个参数,说这个参数必须有一个名为 Update 的方法。

4

2 回答 2

3

您可以使用成员约束和静态解析的类型参数来执行此操作。

let inline ProcessExpendableADGroups (input : (^a * SPUser) seq) = //'
  input
  |> Seq.filter (fun (_, u) -> u.IsDomainGroup && ADUtility.IsADGroupExpandable u.LoginName)       
  |> Seq.iter( 
      fun (li, u) -> 
        let userList = ADUtility.GetUsers u.LoginName 
        if (Seq.length userList <= 500) then
          userList
          |> Seq.filter (fun l -> InfobarrierPolicy.IsUserInPolicy l "FW") 
          |> Seq.iter (
              fun ln ->
                let x = ADUtility.GetNameAndEmail ln 
                let (email, name) = x.Value
                SPUtility.CopyRoleAssignment li u.LoginName ln email name
                (^a : (member Update : unit -> unit) li) //'
              )
          SPUtility.RemoveRoleAssignment li u
      ) 

这里还有一系列关于该主题的有用文章。

我对上面的功能做了一些改进:

  • 一系列Seq.filter可以折叠为一个Seq.filter,并且= true始终是代码气味。
  • List.ofSeq并且List.iter可以替换为Seq.iter. 当您使用 时Seq.iter,无论如何都会评估惰性序列。
  • 不要编写多余的类型注释,例如li: 'au: SPUser。由于您使用管道并具有类型注释input,因此类型检查器将能够推断出正确的类型。
于 2012-09-27T09:23:32.487 回答
2

约束看起来像这样(它不需要在方法声明处 - 只是你使用它的地方)

 (^a: ( member Update: unit-> unit )t))

这将调用Update在对象上调用的方法t

于 2012-09-27T09:22:10.253 回答