C# alternative for using enum as method parameter

c# enum alternative
type safe enum c#
int to enum c#
c# partial enum
c# enum constructor
alternative to enum java
c# string enum
c# enum property

I have the following method that downloads a set of item prices or license prices and stores it on the local HDD. The only difference between the two is the input list that dictates what items that should be queried for. The application is being deployed as a clickonce app so the storage of the file differs from debug to deployment build.

    private const string PRICEFILE = "Resources\\prices.xml";
    private const string RATEFILE = "Resources\\rates.xml";
    private const string INPUTFILE = "Resources\\ItemsList.txt";
    private const string INPUTFILELICENSE = "Resources\\Licenses.txt";
    private const string LICENSEFILE = "Resources\\Licenses.xml";

   public string getFromInventoryTableOnServer(InventoryTypeEnum type)
    {
        string _input = "";
        string _output = "";
        // Get items from items file in resources
        if (ApplicationDeployment.IsNetworkDeployed)
        {
            if (type.Equals(InventoryTypeEnum.Prices))
            {
                _input = ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + INPUTFILE;
                _output = ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + PRICEFILE;
            }
            else if (type.Equals(InventoryTypeEnum.Licences))
            {
                _input = ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + INPUTFILELICENSE;
                _output = ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + LICENSEFILE;
            }
        }
        else
        {
            if (type.Equals(InventoryTypeEnum.Prices))
            {
                _input = INPUTFILE;
                _output = PRICEFILE;
            }
            else if (type.Equals(InventoryTypeEnum.Licences))
            {
                _input = INPUTFILELICENSE;
                _output = LICENSEFILE;
            }
        }


        // Read file
        List<string> items = new List<string>();
        using (var sr = new StreamReader(_input))
        {


            while (!sr.EndOfStream)
            {
                items.Add(sr.ReadLine().Split(new[] { Environment.NewLine }, StringSplitOptions.None)[0]);
            }

        }

        // Connection to database and table
        List<InventTableDW> it;
        using (AXDataContext ax = new AXDataContext())
        {
            var table = ax.GetTable<InventTableDW>();

            // Query AX for item info, specially prices
            var query =
                from p in table
                where items.Contains(p.ItemID) && p.ItemGroupID == "100"
                orderby p.ItemID
                select p;

            try
            {
                it = query.ToList();
            }
            catch (Exception e)
            {
                return e.Message;
            }
        }


        // Write to the price file
        try
        {
            using (var sw = new StreamWriter(_output))
            {
                {
                    var ser = new XmlSerializer(typeof(List<InventTableDW>));
                    ser.Serialize(sw, it);
                }
            }
        }
        catch (Exception e)
        {
            return e.Message;
        }
        return "";
    }

enum InventoryTypeEnum
{
    Prices,
    Licences
}

I'm not very proud of the current implementation as it looks a bit messy. Do you have any improvement suggestions?

Many thanks!


Dictionaries are a good way to get rid of if or switch statements, but I don't like much the nested dictionaries solution proposed by Sam Axe. My solution uses only one Dictionary.

I have created a simple class that will be used as the key of the Dictionary, overriding both the GetHashCode and Equals methods:

internal class Key
{
    public readonly bool IsNetworkDeployed { get; }
    public readonly InventoryTypeEnum InventoryType { get; }

    public Key(InventoryTypeEnum inventoryType, bool isNetworkDeployed=false)
    {
        IsNetworkDeployed = isNetworkDeployed;
        InventoryType = inventoryType;
    }

    protected bool Equals(Key other)
    {
        return IsNetworkDeployed == other.IsNetworkDeployed && 
               InventoryType == other.InventoryType;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;

        return Equals((Key) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (IsNetworkDeployed.GetHashCode() * 397) ^ (int) InventoryType;
        }
    }
}

And, as suggested by Sam, a class to hold the paths:

public class FilePaths
{
    public string InputPath { get; set; } = string.Empty;
    public string OutputPath { get; set; } = string.Empty;
}

Initializing the Dictionary:

private readonly Dictionary<Key, FilePaths> _pathsDictionary = new Dictionary<Key, FilePaths>
{
    {
        new Key(InventoryTypeEnum.Licences, isNetworkDeployed: true),
        new FilePaths {
            InputPath = $@"{ApplicationDeployment.CurrentDeployment.DataDirectory}\{INPUTFILELICENSE}",
            OutputPath = $@"{ApplicationDeployment.CurrentDeployment.DataDirectory}\{LICENSEFILE}"
        }
    },
    {
        new Key(InventoryTypeEnum.Prices, isNetworkDeployed: true), 
        new FilePaths {
            InputPath = $@"{ApplicationDeployment.CurrentDeployment.DataDirectory}\{INPUTFILE}",
            OutputPath = $@"{ApplicationDeployment.CurrentDeployment.DataDirectory}\{PRICEFILE}"
        }
    },
    {
        new Key(InventoryTypeEnum.Licences, isNetworkDeployed: false), 
        new FilePaths {
            InputPath = INPUTFILELICENSE,
            OutputPath = LICENSEFILE
        }
    },
    {
        new Key(InventoryTypeEnum.Prices, isNetworkDeployed: false), 
        new FilePaths {
            InputPath = INPUTFILE,
            OutputPath = PRICEFILE
        }
    }
};

Using the code:

public string GetFromInventoryTableOnServer(InventoryTypeEnum type)
{
    var key = new Key(type, ApplicationDeployment.IsNetworkDeployed);
    FilePaths paths = _pathsDictionary[key];

    // remaining code here ...
}

Enum Alternatives in C#, Now some method accepts this type as a parameter: The pattern creates a class to represent the enumeration, and can even use the same  If you want to pass in the value to use, you have to use the enum type you declared and directly use the supplied value: If you instead want to use a fixed value, you don't need any parameter at all. Instead, directly use the enum value. The syntax is similar to a static member of a class:


Something along the lines of a lookup might make the code more "pretty". Though the effect on maintainability may be dubious. You would need to remember to update the _pathMap variable whenever a path changed. Shouldn't be a big deal.. you have to change them somewhere.

Also, I don't care for the bool key, but I tried to keep it as close to your original function as possible. The bool doesn't instantly convey intent. I would recommend changing it to an enum if at all possible.

private class FilePaths {
    public FilePaths(string inputPath, string outputPath) { 
        InputPath = inputPath;
        OutputPath = outputPath;
    }
    public string InputPath {get; set; } = string.Empty;
    public string OutputPath {get; set; } = string.Empty;
}

enum InventoryTypeEnum {
    Prices,
    Licences
}

private const string PRICEFILE = "Resources\\prices.xml";
private const string RATEFILE = "Resources\\rates.xml";
private const string INPUTFILE = "Resources\\ItemsList.txt";
private const string INPUTFILELICENSE = "Resources\\Licenses.txt";
private const string LICENSEFILE = "Resources\\Licenses.xml";

private Dictionary<bool, Dictionary<InventoryTypeEnum, FilePaths>> _pathMap = 
    new Dictionary<bool, Dictionary<InventoryTypeEnum, FilePaths>>() {
        { true, { InventoryTypeEnum.Prices, 
                  new FilePaths(
                      ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + INPUTFILE,
                      ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + PRICEFILE
                  ) 
        } },
        { true, { InventoryTypeEnum.Licences, 
                  new FilePaths(
                      ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + INPUTFILELICENSE,
                      ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + LICENSEFILE
                  ) 
        } },
        { false, { InventoryTypeEnum.Prices, 
                  new FilePaths(
                      INPUTFILE,
                      PRICEFILE
                  ) 
        } },
        { false, { InventoryTypeEnum.Licenses, 
                  new FilePaths(
                      INPUTFILELICENSE,
                      LICENSEFILE
                  ) 
        } }
    }

public string getFromInventoryTableOnServer(InventoryTypeEnum type) {
    FilePaths paths = _pathMap[ApplicationDeployment.IsNetworkDeployed][type];
    // paths.InputPath and paths.OutputPath should now hold the correct values.

    //  ... rest of function ...
}

Using Enumeration classes instead of enum types, NET Applications | Lear how you can use enumeration classes, instead of C# Copy. public abstract class Enumeration : IComparable { public string Id); // Other utility methods . https://ardalis.com/enum-alternatives-in-c. This C# enum method converts a specified value of a specific enumerated list to another equivalent data type, usually a string. It takes three parameters as arguments, type, object, and format. The first argument, type, is enum type of the value to convert. The second argument, object, is the value to convert.


First of all, move the nested ifs to a separate method that returns a ValueTuple<string, string>. From there on you have a few options, I would like to propose one with a switch.

I think it's best to check for the enum first, in case it will grow in the future, and then check for the boolean. Like this:

enum Animal
{
    Fish,
    Dog,
    Zebra
}

string GetLabel(bool isAwesome, Animal animal)
{
    switch (animal)
    {
        case Animal.Fish:
            return isAwesome ? "awesome fish" : "not so awesome fish";
        case Animal.Dog:
            return isAwesome ? "super awesome dog" : "awesome dog";
        case Animal.Zebra:
            return isAwesome ? "awesome zebra" : "normal zebra";
        default:
            return "is this even an animal?";
    }
}

Not that this is more performant than the nested Dictionarys proposed in another answer.

Enum.Parse Method (System), Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object. A parameter specifies​  Use enumeration classes instead of enum types. 10/08/2018; 2 minutes to read +3; In this article. Enumerations (or enum types for short) are a thin language wrapper around an integral type. You might want to limit their use to when you are storing one value from a closed set of values. Classification based on sizes (small, medium, large) is a


Named and Optional Arguments, Both techniques can be used with methods, indexers, constructors, and delegates. When you use named and optional arguments, the arguments are new ValType() , where ValType is a value type, such as an enum or a  The main alternative to using Enums (wich are little more then Grouped Compile time integer Constants) is a array, list or other collection. Somthing like a dictionary <int, soemthing> migth work better as you can easily do a key loockup to check if the input is valid. – Christopher Jun 16 '18 at 20:34


out parameter modifier, The following example uses out to return three variables with a single method call. The third argument is assigned to null. This enables methods  C# Enums. An enum is a special "class" that represents a group of constants (unchangeable/read-only variables).. To create an enum, use the enum keyword (instead of class or interface), and separate the enum items with a comma:


C# enum Examples, C# program that uses enums using System; class Program { enum ToString: Internally, ToString invokes methods that use reflection to acquire the default: { // The argument is not a format value. return false; } } } } Output True Upon class creation, an enum field will also be initialized to zero (and the equivalent value). In C#, enum is a value type data type. The enum is used to declare a list of named integer constants. It can be defined using the enum keyword directly inside a namespace, class, or structure. The enum is used to give a name to each constant so that the constant integer can be referred using its name.