I have a List that I want to compare to an Enum
.
If a.Value
is found in the Enum
we return true
.
I feel that I should be able to make this a single line, but have struggled.
private bool IsFound(IEnumerable<SomeAttribute> attributes)
{
foreach (AttributesInMethod option in Enum.GetValues(typeof(AttributesInMethod)))
{
if (attributes.Any(a => option.GetDisplayNameENUM().Contains(a.Value)))
{
return true;
}
}
return false;
}
1 Answer 1
I would suggest a two lines of code solution instead of one. :)
Let me show you first the solution then the explanation.
Solution
private static readonly Lazy<IEnumerable<string>> enumValues = new Lazy<IEnumerable<string>>(() => Enum.GetValues(typeof(AttributesInMethod)).Cast<AttributesInMethod>().Select(option => option.GetDisplayNameENUM()));
private bool IsFound(IEnumerable<SomeAttribute> attributes) => attributes.Select(att => att.Value).Any(enumValues.Value.Contains);
Explanation
Two methods instead of one
- You have two kinds of data
- A fairly static data, which could be changed only with code change
- The mapped values of the enumeration
- An absolutely dynamic data, which could change by each and every method call
- The
IsFound
input parameter
- The
- A fairly static data, which could be changed only with code change
You don't need to calculate each and every time the derived data from the enumeration. It should be calculated once and stored for long term.
Usage of Lazy
"It should be calculated once and stored for long term." > That's where the Lazy<T>
type comes into play.
All you have to do is to provide a factory method (how to compute the derived data) and then the calculated information should be stored in a long-living variable. Lazy<T>
gives us thread-safety so there is a guarantee that it will be calculated only once.
How to derive the data
Enum.GetValues(typeof(AttributesInMethod))
.Cast<AttributesInMethod>()
.Select(option => option.GetDisplayNameENUM())
GetValues
returns an Array
so you have to call Cast<T>
to be able to use Linq operator on it.
Composing functions
For each input data check the existence of it in a predefined collection.
- For each input data:
attributes.Select(att => att.Value)
- check the existence of it:
.Any(... .Contains)
- in a predefined collection:
enumValues.Value
All you have to do to compose them to create a new higher level function.