Hello,
I have a class as follows:
public class User {
public Int32 Id { get; set; }
public IList<Role> Roles { get; set; }
} // User
The Role class as a property NAME. I have the following string array:
String[] filterRoles = { "role2", "role4 };
I need to select all users which roles contains at least of of these roles.
How can I do this?
Arne already gave you an example. But if you do this quite often, you
might prefer other implementations, because Intersect is quite slow. (It
creates a temporary hash table on each invocation.)
The first improvement could be, that you use a sorted list or a
dictionary for Roles, using NAME as a key. (This requires that Role.NAME
is immutable.)
public IDictionary<string,Role> Roles { get; set; }
Now you can define a extension function
public static bool IsInRoles(this IDictionary<string,Role> roles,
params string[] names)
{ return names.Any(name => roles.ContainsKey(name));
}
Using a class Roles that inherits from IDictionary<string,Role> makes
things even more readable.
If the set of roles that your application can handle is limited, then
you might further use a flags enum. This is extremely fast and memory
conserving.
[Flags]
enum Roles
{ none = 0
role1 = 1 << 0,
role2 = 1 << 1,
role3 = 1 << 2,
role4 = 1 << 3,
...
}
Now your Roles property is of type Roles rather than IList<...>.
public Roles Roles { get; set; }
Checking for a permission is now a very simple bit operation. You could
again use a extension method.
public static bool IsInRoles(this Roles roles1, Roles roles2)
{ return (roles1 & roles2) != 0;
}
The drawback is, that you need to convert the strings to the enum type
once. But if the naming is consistent with the enum identifiers this is
quite easy.
public static Roles ParseRoles(string[] names)
{ return names.Aggregate(Roles.none, (roles,name) =>
roles | (Roles)Enum.Parse(typeof(Roles), name, true));
}
Marcel