是否可以在枚举中保存类型(使用"typeof()")?

Kei*_*A45 61 c# enums types type-conversion

所以我在XNA,C#4.0中创建一个游戏,我需要管理很多PowerUps(在代码中都继承自"PowerUp"类),并处理PowerUps的后端管理我目前有一个枚举,PowerupEffectType,具有PowerUp的每个子类的值.最终在代码中我需要进行从PowerupEffectType到Powerup类型的转换(Type通常用类实现typeof([class name])).

由于这是一个组项目,我想尽可能将PowerupEffectType的每个值与其对应的类Type结合,即:不仅仅是期望我的其他程序员使用switch语句手动进行转换,并确保以后添加/扩展在尽可能少的地方进行尽可能少的变更.我有几个选项,到目前为止我发现的最好的是创建枚举伪方法,将所有内容压缩到一个switch语句(我想要的99%),这要归功于我在这里找到的一些提示:http ://msdn.microsoft.com/en-us/library/bb383974.aspx

但我试图更进一步 - 我可以保存Type一个enum吗?我知道你可以将枚举保存为特定类型(链接:http://msdn.microsoft.com/en-us/library/cc138362.aspx),但Type不是其中之一.当前选择是byte,sbyte,short,ushort,int,uint,long和ulong.是否有任何可行的方法将转换a保存Type到上述任何数据类型并返回?

为了清楚起见,这就是我希望我能做到的,我正在寻找一种方法:

// (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)
}
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点,或者我只是过度复杂解决了已经99%完成的问题?

提前致谢!

Jon*_*eet 93

您不能将其作为枚举的,但您可以在属性中指定它:

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
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在执行时使用反射提取这些属性值.但是,我个人只会创建一个字典:

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

不需要特殊属性,不需要使用fiddly反射代码提取值.


naw*_*fal 18

这不是你要求的.我发现Jon的属性方法最好.但为什么不将它包装在扩展方法中呢?

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

PowerupEffectType e = PowerupEffectType.WATER;
var t = e.GetPowerupEffectType();
Run Code Online (Sandbox Code Playgroud)


mlo*_*ske 16

这样的事怎么样?

您可以获得使用枚举执行的类型安全性,以及对Type的隐式转换

public class PowerupEffectType
{
    private readonly Type _powerupType;

    public static implicit operator Type(PowerupEffectType powerupEffectType)
    {
        return powerupEffectType._powerupType;
    }

    private PowerupEffectType(Type powerupType)
    {
        _powerupType = powerupType;
    }

    public static readonly PowerupEffectType LIGHTNING = new PowerupEffectType(typeof(LightningPowerup));
    public static readonly PowerupEffectType FIRE = new PowerupEffectType(typeof(FirePowerup));
    public static readonly PowerupEffectType WATER = new PowerupEffectType(typeof(WaterPowerup));
}
Run Code Online (Sandbox Code Playgroud)

  • 只需转换为'Type'(Type)PowerupEffectType.FIRE (3认同)
  • 这绝对是最接近OP想要的.为了更好,[XML doc标签`完成列表`](http://stackoverflow.com/a/102217/1968)可用于为此类型提供枚举式自动完成 - 但不幸的是仅在VB中,而不是对于C#. (2认同)

ben*_*er3 9

你可以用一个static Dictionary<PowerupEffectType, Powerup>.我相信那将是你正在寻找的那种"婚姻".它可以轻松枚举和访问.