您如何比较两个不同文件夹的AuthorizationRuleCollection?我想知道ACL是否相同。
我的解决方案是遍历每个项目并计算IdentityReference.Value + AccessMask的哈希值。然后将它们汇总起来,比较每个集合的总数。
有更好的方法吗?
答案 0 :(得分:2)
由于SequenceEqual
实现了IEnumerable
,因此我将使用LINQ中的AuthorizationRuleCollection
。唯一的问题是AuthorizationRule
不会覆盖object.Equals()
,这意味着我们需要像这样提供自定义IEqualityComparer<AuthorizationRule>
:
public class AuthorizationRuleEqualityComparer : IEqualityComparer<AuthorizationRule>
{
public static readonly AuthorizationRuleEqualityComparer Instance = new AuthorizationRuleEqualityComparer();
private AuthorizationRuleEqualityComparer()
{
}
public bool Equals(AuthorizationRule l, AuthorizationRule r)
{
// Compare more fields if needed.
return l.IdentityReference == r.IdentityReference;
}
public int GetHashCode(AuthorizationRule rule)
{
return rule.IdentityReference.GetHashCode();
}
}
用法:
AuthorizationRuleCollection arc1;
AuthorizationRuleCollection arc2;
var equal = arc1
.OfType<AuthorizationRule>()
.SequenceEqual(
arc2.OfType<AuthorizationRule>(),
AuthorizationRuleEqualityComparer.Instance);
答案 1 :(得分:0)
即使集合内的顺序不同,这似乎也可以正常工作
internal static bool IsEqual(this AuthorizationRuleCollection authorizationRuleCollectionA, AuthorizationRuleCollection authorizationRuleCollectionB)
{
if (authorizationRuleCollectionA.Count != authorizationRuleCollectionB.Count)
{
return false;
}
int hash1 = CalculateHash(authorizationRuleCollectionA);
int hash2 = CalculateHash(authorizationRuleCollectionB);
return hash1 == hash2;
}
/// <summary>
/// Source: https://stackoverflow.com/a/263416/10585750
/// </summary>
/// <param name="authorizationRuleCollection"></param>
private static int CalculateHash(AuthorizationRuleCollection authorizationRuleCollection)
{
unchecked
{
int hash = 17;
foreach (FileSystemAccessRule fileSystemAccessRule in authorizationRuleCollection)
{
hash += CalculateHash(fileSystemAccessRule);
}
return hash;
}
}
private static int CalculateHash(FileSystemAccessRule fileSystemAccessRule)
{
unchecked
{
int hash = 23 * fileSystemAccessRule.IdentityReference.Value.GetHashCode()
* fileSystemAccessRule.InheritanceFlags.ToString().GetHashCode()
* fileSystemAccessRule.IsInherited.ToString().GetHashCode()
* fileSystemAccessRule.PropagationFlags.ToString().GetHashCode()
* fileSystemAccessRule.FileSystemRights.ToString().GetHashCode()
* fileSystemAccessRule.AccessControlType.ToString().GetHashCode();
return hash;
}
}