title: Map enum to a function/action using enum-specific method
body: <p>I'm working on an online booking site (airline) and I want to validate if the user/customer's chosen route is valid according to some settings. The existing codes uses a lot of enums and I found myself doing lots of if/if else/else to map a specific enum to a particular action that I wanted to happen. <code>What I want to do is to write a enum-specific method that would do the mapping for me. Is there any standard way to do this?</code></p>
  
  <p>Here's a simplified version of the app code using the same class names/enum values etc from the real app:</p>
  
  <pre><code>// real app has 9 members, shortened for simplicity's sake
  public enum RegionType
  {
      Station,
      Country,
      All
  }
  
  public enum Directionality
  {
      Between,
      From,
      To
  }
  
  // simplified version
  public class Flight
  {
       public RegionType RegionType { get; set; }
       public RegionType TravelRegionType { get; set; }
       public string RegionCode { get; set; }
       public string TravelRegionCode { get; set; }
       public string RegionCountryCode { get; set; }
       public string TravelRegionCountryCode { get; set; }
       public Directionality Directionality { get; set; }
  }
  </code></pre>
  
  <p>Here's some sample usage:</p>
  
  <pre><code>    // valid flight
      Flight flight = new Flight()
      {
          RegionCode = "NY",
          CountryCode = "JP",
          RegionType = RegionType.Station,
          TravelRegionType = RegionType.Country,
          Directionality = Directionality.Between
      };
  
      // these are the station code/country code that user selected
      // needs to be validated against the Flight object above
      var userSelectedRoutes = new List&lt;KeyValuePair&lt;string, string&gt;&gt;() 
      { 
          new KeyValuePair&lt;string, string&gt;("NY", "JP"),
          new KeyValuePair&lt;string, string&gt;("NY", "AU"),
          new KeyValuePair&lt;string, string&gt;("JP", "NY")
      };
  </code></pre>
  
  <p>Some code validation I wrote to lessen nested if/else if/else enum matching:</p>
  
  <pre><code>private bool IsRouteValid(Directionality direction, string origin, 
                            string destination, string departure, string arrival)
  {
      // both departure station and arrival station
      if (direction == Directionality.Between)
      {
          return (origin.Equals(departure, StringComparison.OrdinalIgnoreCase) 
            &amp;&amp; destination.Equals(arrival, StringComparison.OrdinalIgnoreCase)
                 || origin.Equals(arrival, StringComparison.OrdinalIgnoreCase) 
            &amp;&amp; destination.Equals(departure, StringComparison.OrdinalIgnoreCase));
      }
      else if (direction == Directionality.From)
      {
              return (origin.Equals(departure, 
                      StringComparison.OrdinalIgnoreCase));   
      }
      else if (direction == Directionality.To)
      {
              return (destination.Equals(arrival, 
                      StringComparison.OrdinalIgnoreCase));
      }
  
      return false;
  }
  </code></pre>
  
  <p>And here's the messy code I want to change: </p>
  
  <pre><code>if (flight.RegionType == RegionType.Station 
      &amp;&amp; flight.TravelRegionType == RegionType.Country)
  {
       return userSelectedRoutes.Any(route =&gt; 
              IsRouteValid(flight.Directionality, route.Key, route.Value,
              flight.RegionCode, flight.TravelRegionCode));
  }
  else if (flight.RegionType == RegionType.Country 
  &amp;&amp; flight.TravelRegionType == RegionType.Station)
  {
      return userSelectedRoutes.Any(route =&gt; 
             IsRouteValid(flight.Directionality, route.Key, route.Value,
             flight.CountryCode, flight.RegionCode));
  }
  else if (flight.RegionType == RegionType.Station 
  &amp;&amp; flight.TravelRegionType == RegionType.Station)
  {
      return userSelectedRoutes.Any(route =&gt; 
             IsRouteValid(flight.Directionality, route.Key, route.Value,
                         flight.RegionCode, flight.TravelRegionCode));
  }
  else if (flight.RegionType == RegionType.Station 
  &amp;&amp; flight.TravelRegionType == RegionType.All)
  {
      return userSelectedRoutes.Any(route =&gt; 
             IsRouteValid(flight.Directionality, route.Key, route.Value,
                         flight.RegionCode, route.Value));
  }
  else if (flight.RegionType == RegionType.All 
  &amp;&amp; flight.TravelRegionType == RegionType.Station)
  {
      return userSelectedRoutes.Any(route =&gt;
             IsRouteValid(flight.Directionality, route.Key, route.Value,
             route.Key, flight.TravelRegionCode));
  }
  else if (flight.RegionType == RegionType.All 
          &amp;&amp; flight.TravelRegionType == RegionType.All)
  {
      return true;
  }
  else
  {
      return false;
  } 
  </code></pre>
  
  <p><strong>Legend:</strong></p>
  
  <p><code>RegionCode</code> = departure station/origin <br />
  <code>TravelRegionCode</code> = arrival station/destination <br />
  <code>Between</code> = routes must be only from the given departure station and arrival station and vice-versa (ex NY-JP or JP-NY) <br />
  <code>From</code> = from particular station to any routes (ex AU-<em>All</em>) <br />
  <code>To</code> = any routes to a particular station (ex <em>All</em>-AU)</p>
  
  <p>If you could notice, the <code>.Any</code> of all the conditions above are same with slight changes. I want to reduce code redundancy, if possible. I used <code>KeyValuePair</code> so I have both departure station and arrival station on a single data type.</p>
  
  <p>Any ideas on how could I make this code less messy/beautiful? I know I also hard coded <code>IsRouteValid()</code> but I'm 100% sure that <code>Directionality</code> could only have the 3 possible combinations. <code>RegionType</code> on the other hand could have several several combinations like Station-Station, Station-Country, Country-Station, Country-Country etc. </p>
  
  <p><strong>Expected Output:</strong> </p>
  
  <p>Valid/True for first route (NY-JP) <br />
  Invalid/False for second route (NY-AU)  <br />
  Valid/True for third route (JP-NY) [since <code>Directionality</code> is <code>Between</code>]</p>
  
  <p>Thank you for reading this very long query and thanks in advance for your feedback and suggestions.</p>
  
  <p><strong>Similar post:</strong></p>
  
  <p><a href="https://stackoverflow.com/questions/10033077/enum-and-dictionaryenum-action">Enum and Dictionary</a></p>