Establecer el valor subyacente de System.Enum

I have an enumeration that is a member variable of an object. I don't know the enumeration's exact type, only that it is derived from System.Enum. I want to set the enumeration's underlying numeric value. In other words:

Enum e;
// ...
e = 42;  // Doesn't comple

Is this possible? Can it be done with reflection?

Edit 1: The enum is part of a larger data structure, so creating a new value using Enum.ToObject() is not suitable.

Edit 2: Clarified that the enum is a member variable of an object.

Edit 3: Since a few commenters have asked for more context, heres a summary: I have some general-purpose code that is supposed to associate UI controls (text boxes, etc) with corresponding fields in an object data model. When the UI changes the model is updated, and vice-versa. I was looking at extending this to map between combo boxes and enumerations; where the enum would be set to the index of the selected combo entry. Setting the selected item from the enum's underlying value is trivial, but the reverse of this is where the problem occurs. I was fairly sure that this wasn't going to be possible, but thought it was worth asking.

preguntado el 28 de agosto de 12 a las 15:08

You should know that even if you do this, it won't change the value of the Enum that got passed in to your function. What are you trying to do? -

btw, it might help to clarify what you mean be "a reference to an enumeration". To be a direct reference to the value, you would need to know the type (even if it was just a T in a generic method); otherwise, you're probably using a reference to a copia en caja, not the original value itself -

It's the answer to life the universe and everything! To use Enums you need to know their design, you could have found this. Downvote for wasted time. -

Usted ya haya utilizado made a copy outside the larger data structure when you passed it as an Enum. You need to redesign your function to take a byref T. -

@MrFox Thanks for the downvote and for your extremely helpful comment. -

2 Respuestas

Note that it's not actually possible to change the value of the object itself, but you can get a new object of the same type. Depending on what you're trying to do, this may not work for you. What are you trying to do?

e = Enum.ToObject(e.GetType(),42)

Okay, the best thing you can do here, I think, is:

void SetTo42<T>(out T e) {
    e = (T)Enum.ToObject(typeof(T), e);
}

This is a very strange thing to want to do, though, so I have to ask whether maybe you should rethink your design.


Okay, I am going to go out on a limb and guess what you are trying to do - I am assuming your "Enum e" comes from using GetValue, and that you therefore have a FieldInfo (or PropertyInfo)

void SetFieldTo42(Object obj, FieldInfo f) {
    f.SetValue(obj,Enum.ToObject(f.FieldType, 42));
}

Respondido 28 ago 12, 15:08

Thanks! Unfortunately using Enum.ToObject() is unsuitable for what I'm trying to do because the enum to be set is part of a larger data structure. I have edited the question to note this. - Andy Johnson

Necesitas Enum.ToObject cuando estas haciendo SetValue? - Gabe

@Gabe Dunno. Try it - I suspect that it will fail without it because you're trying to set the value to the wrong type (System.Int32) - Random832

No, it worked fine for me. I think it was only .NET 1 where Reflection wouldn't assign an integer to an enum. - Gabe

You need to know the enum's Type at tiempo de ejecución, even if you don't know it at en tiempo de compilación - bacause Enum is a boxed value, and in order to box something you need to have access to the type (so that .GetType() returns the right thing); for example, doing this at runtime:

public Enum GetEnumValue(Type type) {
    return (Enum)Enum.ToObject(type, 42);
}

Respondido 28 ago 12, 15:08

Thanks for the helpful answer Mark. The problem arose out of my considering extending some existing code (see my edit 3 in the question) and you've confirmed that that it can't be done. - Andy Johnson

@AndyJohnson note: if you actually have a SomeFunc<T>(ref T value), then it probably pueden still be done, but will probably require ILGenerator para hacerlo - marc gravell

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.