Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to save a Type (using "typeof()") in an enum?

So I'm creating a game in XNA, C# 4.0, and I need to manage a lot of PowerUps (which in code are all inherited from class "PowerUp"), and to handle back-end management of the PowerUps I currently have an enum, PowerupEffectType, with a value for each child class of PowerUp. Eventually in the code I need to do conversions from PowerupEffectType to the Powerup type (of class Type, achieved usually with typeof([class name])).

Since this is a group project, I want to marry each value of PowerupEffectType to its corresponding class Type as well as possible, i.e.: Not just expect my other programmers to use switch statements to do the conversion manually, and making sure additions/expansions later involve as few changes in as few places as possible. I have a few options for this, and the best I've discovered so far is creating enum pseudo-methods that condense everything down to a single switch statement (99% of what I want), thanks to some tips I found here: http://msdn.microsoft.com/en-us/library/bb383974.aspx

But I'm trying to take it one step further - can I save a Type in an enum? I know you can save enums as a specific type (link: http://msdn.microsoft.com/en-us/library/cc138362.aspx), but Type isn't one of them. The current choices are byte, sbyte, short, ushort, int, uint, long, and ulong. Is there any feasible way to save a convert a Type to any of the above data types and back?

Just to be clear, this is what I WISH I could do, and I'm looking for a way to do:

// (Assuming 'LightningPowerup', 'FirePowerup', and 'WaterPowerup' are // all declared classes that inherit from a single base class)  public enum PowerupEffectType {     LIGHTNING = typeof(LightningPowerup),     FIRE = typeof(FirePowerup),     WATER = typeof(WaterPowerup) } 

Is there any way to do this, or am I just overcomplicating a solution to a problem that's already 99% complete?

Thanks in advance!

like image 320
KeithA45 Avatar asked Jun 13 '12 05:06

KeithA45


People also ask

Is enum value type or reference?

Enum is a reference type, but any specific enum type is a value type. In the same way, System. ValueType is a reference type, but all types inheriting from it (other than System. Enum ) are value types.

How do you check if a type is an enum?

In C#, we can check the specific type is enum or not by using the IsEnum property of the Type class. It will return true if the type is enum. Otherwise, this property will return false. It is a read-only property.

Why is enum value type?

Enum is Reference Type or Value Type? enumerations are of value type. They are created and stored on the stack and passed to the methods by making a copy of the value (by value). Enums are value type.


2 Answers

You can't do it as the value of an enum, but you could specify it in an attribute:

using System; using System.Runtime.CompilerServices;  [AttributeUsage(AttributeTargets.Field)] public class EffectTypeAttribute : Attribute {     public Type Type { get; private set; }      public EffectTypeAttribute(Type type)     {         this.Type = type;     } }  public class LightningPowerup {} public class FirePowerup {} public class WaterPowerup {}  public enum PowerupEffectType {     [EffectType(typeof(LightningPowerup))]     Lightning,     [EffectType(typeof(FirePowerup))]     Fire,     [EffectType(typeof(WaterPowerup))]     Water } 

You can then extract those attribute values at execution time with reflection. However, I would personally just create a dictionary:

private static Dictionary<PowerupEffectType, Type> EffectTypeMapping =     new Dictionary<PowerupEffectType, Type> {     { PowerupEffectType.Lightning, typeof(LightningPowerup) },     { PowerupEffectType.Fire, typeof(FirePowerup) },     { PowerupEffectType.Water, typeof(WaterPowerup) } }; 

No need for a special attribute, no need to extract the values with fiddly reflection code.

like image 151
Jon Skeet Avatar answered Sep 17 '22 14:09

Jon Skeet


This is not exactly what u are asking for. I find Jon's attribute method the best. But why not wrap it in an extension method?

public Type GetPowerupEffectType(this PowerupEffectType powerEffect) {     switch (powerEffect)     {         case LIGHTNING:             return typeof(LightningPowerup);         case FIRE:             return typeof(FirePowerup);         case WATER:             return typeof(WaterPowerup);         default:             return default(Type);     } } 

And call it:

PowerupEffectType e = PowerupEffectType.WATER; var t = e.GetPowerupEffectType(); 
like image 35
nawfal Avatar answered Sep 20 '22 14:09

nawfal