2

I have a class with properties such as :

[TypeConverter(typeof(SomeNameEnumValueConvert))]
public Example ExampleName { get; set; }

In my Enum TypeConverter, I try to get the Enum name from a certain integer, because the source is reading from a table consisting of strings.

In the table, it is stored as e.g. "33" (so not the name), e.g. from

public enum Example
{
    Off = 1,
    On = 33,
    Whatever = 7
}

Then here piece of my converter code:

public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
    var enumValue = Convert.ToInt32(value);
    return  (context.PropertyDescriptor.PropertyType) enumValue
}

However, it gives here that context is a variable, not a type. So I have tried various ways to get this to work but parallel to this I will post it here, maybe that speeds up retries. I have tried casting to Enum, casting to (enum)(object), casting via GetType, casting via Assembly get the specific type but none of this seems to work. Ergo how to convert to the underlying system type.

Klaus Gütter
  • 11,151
  • 6
  • 31
  • 36
edelwater
  • 2,650
  • 8
  • 39
  • 67
  • 1
    I wanted to know if I have understood you correctly: You want to get `Example.off` or `Example.On` or `Example.Whatever` according the value of `enumValue`? – Code Pope Jan 15 '19 at 06:09
  • 1
    `context.PropertyDescriptor.PropertyType` is a `Type` object. You can not cast `value` to a `Type` – Hasan Emrah Süngü Jan 15 '19 at 06:11
  • @Code Pope: yes, I read a table with strings only (key value pairs) and have a strongly typed object. In that strongly typed object I have an enum property. So that needs to be set when reading in the table. So I annotated that enum property with the typeconverter. – edelwater Jan 15 '19 at 06:13
  • Do you want to get a string representation, ie: `Off`,or `On` or numerical value such as 1 or 33 or Do you want to go to Enum from string representation? – Hasan Emrah Süngü Jan 15 '19 at 06:13
  • 1
    You are after `Enum.Parse` or `Enum.TryParse` – Hasan Emrah Süngü Jan 15 '19 at 06:14
  • @HasanEmrahSüngü So i have "3" coming in, how should I then use Enum.Parse? I think Enum.Parse is based on Type (which is the problem) and the value. – edelwater Jan 15 '19 at 06:19
  • @edelwater, "3 " is not defined in your Example enums – Hasan Emrah Süngü Jan 15 '19 at 06:19
  • As long as the question is clear take e.g. "33" instead of "3". So e.g. (context.PropertyDescriptor.PropertyType).GetEnumValues() will work but not (context.PropertyDescription.PropertyType) enumValue – edelwater Jan 15 '19 at 06:22
  • 1
    In my previous comment explained why you CAN NOT do `(context.PropertyDescription.PropertyType)enumvalue` – Hasan Emrah Süngü Jan 15 '19 at 06:24
  • `return Enum.Parse(context.PropertyDescriptor.PropertyType, enumValue);` – Ian Kemp Jan 15 '19 at 06:25
  • @Ian Kemp, the second argument here is a string, I have "33" ,see above, but I think your hint on ToObject is probably going somewhere. – edelwater Jan 15 '19 at 06:30
  • @edelwater, many people are suggesting the same answer but you say it is not correct. Could you please explain why the suggested version does not work? – Hasan Emrah Süngü Jan 15 '19 at 06:32
  • This is a type converter with an incoming int value, TryParse has a string as second parameter with the name of the specific Enum not the assigned value. ToObject has this value but returns the value So i still need to ((context.PropertyDescription.PropertyType)enumvalue but the (context.PropertyDescription.PropertyType) is not the correct type. – edelwater Jan 15 '19 at 06:42
  • @edelwater, You CAN NOT do `(context.PropertyDescription.PropertyType) enumValue`. Why because `(context.PropertyDescription.PropertyType)` is a `Type`. You can not directly cast to `Type` instance – Hasan Emrah Süngü Jan 15 '19 at 06:52
  • @edelwater `Enum.Parse` takes a string, but that string can either be the enum field like "On", or the integer value as a string e.g. "33". So there should be no difference between `Parse` and `ToObject` in your case, IMO. But glad you got it sorted. – Ian Kemp Jan 15 '19 at 07:28

3 Answers3

2

To get the enum name (e.g. "On") from the value, you can use Enum.GetName:

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
    var enumValue = Convert.ToInt32(value);
    return Enum.GetName(context.PropertyDescriptor.PropertyType, enumValue);
}

To get the enum member (e.g. Example.On) from the value, use Enum.ToObject:

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
    var enumValue = Convert.ToInt32(value);
    return Enum.ToObject(context.PropertyDescriptor.PropertyType, enumValue);
}
Klaus Gütter
  • 11,151
  • 6
  • 31
  • 36
1

You could try this if you want a generic solution:

public static class Example
{
    enum Day { Sun, Mon, Tue, Wed, Thu, Fri, Sat };

    public static void Foo()
    {
        Day day = Day.Tue;
        int dayIndex = day.ToInt();
        // dayIndex = 2
        Day result = (dayIndex + 2).ToEnum<Day>();
        // result = Thu
    }

    public static int ToInt<T>(this T t) where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("T must be an enumeration type");
        }
        return Convert.ToInt32(t);
    }

    public static T ToEnum<T>(this int i) where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("T must be an enumeration type");
        }
        return (T)Enum.ToObject(typeof(T), i);
    }
}
Felix D.
  • 4,811
  • 8
  • 38
  • 72
-1

Just try this in your converter:

Example expEnum = (Example)Enum.Parse(typeof(Example), value.ToString(), true);
return expEnum;
Mohammad Nikravesh
  • 947
  • 1
  • 8
  • 27
  • You completely ignored what the question was asking just to post a generic "use Enum.Parse" answer in the hope of farming reputation. – Ian Kemp Jan 15 '19 at 06:29
  • @IanKemp there is no even "generic" work in the question! this is just your opinion, Let Edelwater talk about this. Thanks – Mohammad Nikravesh Jan 15 '19 at 06:32
  • 1
    typeof(Example) with typeof(context.PropertyDescriptor.PropertyType) gives "variable but used like a type", the second parameter is an int in my case not a string? – edelwater Jan 15 '19 at 06:46