Polymorphic state transitions

How to handle Enums without using switch or if statements in C #?

Example

enum Pricemethod { Max, Min, Average } 

... and I have an Article class

  public class Article { private List<Double> _pricehistorie; public List<Double> Pricehistorie { get { return _pricehistorie; } set { _pricehistorie = value; } } public Pricemethod Pricemethod { get; set; } public double Price { get { switch (Pricemethod) { case Pricemethod.Average: return Average(); case Pricemethod.Max: return Max(); case Pricemethod.Min: return Min(); } } } } 

I want to avoid the switch statement and make it general.

For a specific Pricemethod, a specific calculation is called and returns it.

 get { return CalculatedPrice(Pricemethod); } 

Which template should be used here, and maybe someone has a good implementation idea. Already searched for a state template, but I don’t think this is the right option.

+6
source share
2 answers

how to handle enums without using switch or if in c #?

No. enums are just a nice syntax for writing const int .

Consider this template:

 public abstract class PriceMethod { // Prevent inheritance from outside. private PriceMethod() {} public abstract decimal Invoke(IEnumerable<decimal> sequence); public static PriceMethod Max = new MaxMethod(); private sealed class MaxMethod : PriceMethod { public override decimal Invoke(IEnumerable<decimal> sequence) { return sequence.Max(); } } // etc, } 

And now you can say

 public decimal Price { get { return PriceMethod.Invoke(this.PriceHistory); } } 

And the user can say

 myArticle.PriceMethod = PriceMethod.Max; decimal price = myArticle.Price; 
+11
source

You can create an interface and class es that implement it:

 public interface IPriceMethod { double Calculate(IList<double> priceHistorie); } public class AveragePrice : IPriceMethod { public double Calculate(IList<double> priceHistorie) { return priceHistorie.Average(); } } // other classes public class Article { private List<Double> _pricehistorie; public List<Double> Pricehistorie { get { return _pricehistorie; } set { _pricehistorie = value; } } public IPriceMethod Pricemethod { get; set; } public double Price { get { return Pricemethod.Calculate(Pricehistorie); } } } 

Edit: another method uses Dictionary to display Func s, so you don't need to create classes just for that (this code is based on Servy code, which has since deleted its answer):

 public class Article { private static readonly Dictionary<Pricemethod, Func<IEnumerable<double>, double>> priceMethods = new Dictionary<Pricemethod, Func<IEnumerable<double>, double>> { {Pricemethod.Max,ph => ph.Max()}, {Pricemethod.Min,ph => ph.Min()}, {Pricemethod.Average,ph => ph.Average()}, }; public Pricemethod Pricemethod { get; set; } public List<Double> Pricehistory { get; set; } public double Price { get { return priceMethods[Pricemethod](Pricehistory); } } } 
+5
source

Source: https://habr.com/ru/post/956497/


All Articles