public static void Main()
var permission = (Permission<Policy>)0;
Console.WriteLine("所有權限: {0}", permission.AllValue);
Console.WriteLine("當前權限: {0} ({1})", permission, permission.Value);
Console.WriteLine("加入權限 {0}...", Policy.Create);
permission.Add(Policy.Create);
Console.WriteLine("當前權限: {0} ({1})", permission, (BigInteger)permission);
Console.WriteLine("加入權限 {0}...", Policy.Read);
permission.Add(Policy.Read);
Console.WriteLine("當前權限: {0} ({1})", permission, permission.Value);
Console.WriteLine("是否含權限 {0}: {1}", Policy.Read, permission.Contains(Policy.Read));
Console.WriteLine("移除權限 {0}...", Policy.Read);
permission.Remove(Policy.Read);
Console.WriteLine("當前權限: {0} ({1})", permission, permission.Value);
Console.WriteLine("是否含權限 {0}: {1}", Policy.Read, permission.Contains(Policy.Read));
var permissionA = new Permission<Policy>(Policy.Create);
var permissionB = new Permission<Policy>(Policy.Read);
var permissionC = permissionA + permissionB;
var permissionD = permissionC - permissionB;
Console.WriteLine("permissionC: {0} ({1})", permissionC, permissionC.Value);
Console.WriteLine("permissionD: {0} ({1})", permissionD, permissionD.Value);
public class Permission<T>
public BigInteger AllValue
return Enum.GetValues(typeof(T)).OfType<T>().Where(Contains).ToArray();
public Permission(): this(0)
public Permission(params T[] policies): this(ConvertToValue(policies))
public Permission(int value): this((BigInteger)value)
public Permission(BigInteger value)
private static BigInteger ConvertToValue(params T[] policies)
return policies.Aggregate((BigInteger)0, (total, next) => total | (BigInteger)Math.Pow(2, (int)Enum.Parse(typeof(T), next.ToString())));
public void Init(BigInteger value)
this.AllValue = ConvertToValue(Enum.GetValues(typeof(T)).OfType<T>().ToArray());
public void Add(T policy)
this.Value = this.Value | ConvertToValue(policy);
public void Add(Permission<T> permission)
this.Value = (this + permission).Value;
public void Remove(T policy)
this.Value &= this.AllValue ^ ConvertToValue(policy);
public void Remove(Permission<T> permission)
this.Value = (this - permission).Value;
public bool Contains(T policy)
var value = ConvertToValue(policy);
return (this.Value & value) == value;
public static implicit operator BigInteger(Permission<T> permission)
public static implicit operator Permission<T>(BigInteger value)
return new Permission<T>(value);
public static implicit operator int (Permission<T> permission)
return (int)permission.Value;
public static implicit operator Permission<T>(int value)
return new Permission<T>(value);
public static Permission<T> operator +(Permission<T> permissionA, Permission<T> permissionB)
return permissionA.Value | permissionB.Value;
public static Permission<T> operator -(Permission<T> permissionA, Permission<T> permissionB)
return permissionA.Value & permissionA.AllValue ^ permissionB.Value;
public override string ToString()
return string.Join(',', this.Policies);