There is a H-th number of dictionaries with a sheet inside with a list of rights. Is it possible to specify, for example, for 3 dictionaries so that it inherits rights 1 and 2 without iterating over these dictionaries for the desired right?

{ "Default": { "Default": true, "Commands": [ "Test1" ] }, "Vip": { "Default": true, "Commands": [ "Test2" ] }, "Admins": { "Default": true, "Commands": [ "Test3" ] }, "FullAdmins": { "Default": true, "Commands": [ "Test4" ] } } 

    2 answers 2

    Suppose there is data

     Dictionary<string, HashSet<string>> rights = new Dictionary<string, HashSet<string>>() { {"Default", new HashSet<string>(){"Test1"}}, {"Vip", new HashSet<string>(){"Test2"}}, {"Admins", new HashSet<string>(){"Test3"}}, {"FullAdmins", new HashSet<string>(){"Test4"}}, }; string[] groups = new[] { "Default", "Vip", "Admins", "FullAdmins" }; 

    Then with brute force groups everything will be simple

     bool HasRight(string groupName, string rightName) { var ind = Array.IndexOf(groups, groupName); if (ind < 0) return false; for(int i = ind; i>=0; i--) if (rights[groups[i]].Contains(rightName)) return true; return false; } 

    Pts just check

     Console.WriteLine(HasRight("Admins", "Test1")); // true Console.WriteLine(HasRight("Admins", "Test2")); // true Console.WriteLine(HasRight("Admins", "Test3")); // true Console.WriteLine(HasRight("Admins", "Test4")); // false 

    But you need to eat without going through all the elements, then on the basis of the existing dictionary you can assemble a new

     var rights2 = new Dictionary<string, HashSet<string>>(); for (int i = 0; i < groups.Length; i++) { rights2.Add(groups[i], new HashSet<string>()); for (int j = i; j >= 0; j--) { foreach(var right in rights[groups[j]]) rights2[groups[i]].Add(right); } } 

    Then the rights check will look even easier.

     bool HasRight2(string groupName, string rightName, Dictionary<string, HashSet<string>> rights2) { if (!rights2.ContainsKey(groupName)) return false; return rights2[groupName].Contains(rightName); } 

    Test:

     Console.WriteLine(HasRight2("Admins", "Test1", rights2)); // true Console.WriteLine(HasRight2("Admins", "Test2", rights2)); // true Console.WriteLine(HasRight2("Admins", "Test3", rights2)); // true Console.WriteLine(HasRight2("Admins", "Test4", rights2)); // false 

    But in general, I would not recommend collecting new dictionaries, since when the source dictionary changes, the derivative will need to be recompiled.

      I would do this:

      Would create an enumeration

       [Flags] enum Rights { Default = 0x000001, Vip= 0x000002| Default, Admins= 0x000004 | Vip, FullAdmins= 0x000008 | Admins } 

      In your class, instead of a list, would have this bit flag.

      Next, you slyly initialize it.

      And you can use it like this:

        var testRights = Rights.FullAdmins; Console.WriteLine(testRights ); Console.WriteLine($"Имеет права VIP? {testRights.HasFlag(Rights.Vip)}"); Console.WriteLine($"Имеет права Admins{testRights.HasFlag(Rights.Admins)}"); testRights = Rights.Default; Console.WriteLine(testRights ); Console.WriteLine($"Имеет права VIP? {testRights.HasFlag(Rights.Vip)}"); Console.WriteLine($"Имеет права Admins? {testRights.HasFlag(Rights.Admins)}"); 

      It seems to work the way you wanted, since we got rid of listing the classes and the higher roles inherit the rights of the children below.

      enter image description here

      • @ luxa1810 corrected the question - can you lay out an example with the designer? For example so that Admins had access to Test1 without specifying as such - inherited - Sergey
      • As I understand it, you gave an example of such a dictionary with the available rights? Does each right below have the rights of the previous one? If so, you would be satisfied with the implementation through an enumeration with the attribute [Flags] - iluxa1810
      • Yes, it does not - I need to, for example, Admins have the right not only to my Test3, but also to Test2 and Test1, but not to Test4. - Sergey
      • I get Method not found: 'System.Enum.HasFlag "- maybe because of the net framework 3.5? - Sergey
      • What version of the framework? - iluxa1810