5
\$\begingroup\$

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;
}
asked Aug 3, 2020 at 10:31
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

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

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.

answered Aug 3, 2020 at 12:39
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.