我有这段代码
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”的方法。
我已经用Generic参数编写了一个方法但是当我在泛型参数上调用Update时遇到了问题。
我无法限制此参数来表示该参数必须具有名为Update的方法。
答案 0 :(得分:3)
您可以使用成员约束和statically resolved type parameters来执行此操作。
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
)
还有一系列有关该主题here的有用文章。
我对上述功能做了一些改进:
Seq.filter
可以折叠为一个Seq.filter
,= true
始终是代码气味。List.ofSeq
和List.iter
可以由Seq.iter
替换。当您使用Seq.iter
时,无论如何都会评估延迟序列。li: 'a
和u: SPUser
。由于您使用管道并具有input
的类型注释,因此类型检查器将能够推断出正确的类型。答案 1 :(得分:2)
约束看起来就像这样(它不需要在方法中取消 - 就在你使用它的地方)
(^a: ( member Update: unit-> unit )t))
这会在对象Update
t
的方法