Question

I have some factory code that creates objects based on the value of a class member representing an enum:

public enum BeltPrinterType
{
    None,
    ZebraQL220,
    ONiel
    // add more as needed
}

public static BeltPrinterType printerChoice = BeltPrinterType.None;

public class BeltPrinterFactory : IBeltPrinterFactory
{
    // http://stackoverflow.com/questions/17955040/how-can-i-return-none-as-a-default-case-from-a-factory?noredirect=1#comment26241733_17955040
    public IBeltPrinter NewBeltPrinter()
    {
        switch (printerChoice)
        {
            case BeltPrinterType.ZebraQL220: 
                return new ZebraQL220Printer();
            case BeltPrinterType.ONiel: 
                return new ONielPrinter();
            default: 
                return new None();
        }
    }
}

I need to set the value of printerChoice before I call NewBeltPrinter() - that is, if it has been changed from its default "None" value. So I'm trying to assign that value based on the string representation, but have gotten to the proverbial point of no continuance with this attempt:

string currentPrinter = AppSettings.ReadSettingsVal("beltprinter");
Type type = typeof(PrintUtils.BeltPrinterType);
foreach (FieldInfo field in type.GetFields(BindingFlags.Static | BindingFlags.Public))
{
    string display = field.GetValue(null).ToString();
    if (currentPrinter == display)
    {
        //PrintUtils.printerChoice = (type)field.GetValue(null);
        PrintUtils.printerChoice = ??? what now ???
        break;
    }
}

I've tried everything I could think of, and have been repaid with nothing but constant reprimands from the compiler, which has pretty much been dis[mis]sing me as a knave and a sorry rascal.

Does anybody know what I should replace the question marks with?

Was it helpful?

Solution 2

Use Enum.Parse to convert a string into the enum value. (or Enum.TryParse to attempt to do it without raising an exception if it didn't parse)

edit

If you don't have an Enum.Parse available, then you will have to do the conversion yourself:

switch (stringValue)
{
    case "BeltPrinterType.ONiel": enumValue = BeltPrinterType.ONiel; break;
    ...etc...
}

OTHER TIPS

What about just this instead of your second code block:

PrintUtils.printerChoice = (PrintUtils.BeltPrinterType)
    Enum.Parse(typeof(PrintUtils.BeltPrinterType),
               AppSettings.ReadSettingsVal("beltprinter"));

I can't compile to .NET 1.1 but this seems to work in 2.0

PrintUtils.printerChoice = (BeltPrinterType)field.GetValue(null);

EDIT : I just realized this was basically a comment in your code... But yeah I really don't see why this wouldn't work even in 1.1

From the Smart Device Framework 1.x code base:

    public static object Parse(System.Type enumType, string value, bool ignoreCase)
    {
        //throw an exception on null value
        if(value.TrimEnd(' ')=="")
        {
            throw new ArgumentException("value is either an empty string (\"\") or only contains white space.");
        }
        else
        {
            //type must be a derivative of enum
            if(enumType.BaseType==Type.GetType("System.Enum"))
            {
                //remove all spaces
                string[] memberNames = value.Replace(" ","").Split(',');

                //collect the results
                //we are cheating and using a long regardless of the underlying type of the enum
                //this is so we can use ordinary operators to add up each value
                //I suspect there is a more efficient way of doing this - I will update the code if there is
                long returnVal = 0;

                //for each of the members, add numerical value to returnVal
                foreach(string thisMember in memberNames)
                {
                    //skip this string segment if blank
                    if(thisMember!="")
                    {
                        try
                        {
                            if(ignoreCase)
                            {
                                returnVal += (long)Convert.ChangeType(enumType.GetField(thisMember, BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null),returnVal.GetType(), null);
                            }
                            else
                            {
                                returnVal += (long)Convert.ChangeType(enumType.GetField(thisMember, BindingFlags.Public | BindingFlags.Static).GetValue(null),returnVal.GetType(), null);
                            }
                        }
                        catch
                        {
                            try
                            {
                                //try getting the numeric value supplied and converting it
                                returnVal += (long)Convert.ChangeType(System.Enum.ToObject(enumType, Convert.ChangeType(thisMember, System.Enum.GetUnderlyingType(enumType), null)),typeof(long),null);
                            }
                            catch
                            {
                                throw new ArgumentException("value is a name, but not one of the named constants defined for the enumeration.");
                            }
                            //
                        }
                    }
                }


                //return the total converted back to the correct enum type
                return System.Enum.ToObject(enumType, returnVal);
            }
            else
            {
                //the type supplied does not derive from enum
                throw new ArgumentException("enumType parameter is not an System.Enum");
            }
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top