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

时间:2012-06-13 05:43:36

标签: c# types enums type-conversion

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

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

但我正在尝试更进一步 - 我可以在Type中保存enum吗?我知道您可以将枚举保存为特定类型(链接:http://msdn.microsoft.com/en-us/library/bb383974.aspx),但Type不是其中之一。当前选择是 byte,sbyte,short,ushort,int,uint,long和ulong 。有没有可行的方法来保存转换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)
}

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

提前致谢!

7 个答案:

答案 0 :(得分: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
}

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

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

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

答案 1 :(得分: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);
    }
}

并称之为:

PowerupEffectType e = PowerupEffectType.WATER;
var t = e.GetPowerupEffectType();

答案 2 :(得分:16)

这样的事情怎么样?

您获得了使用枚举执行的类型安全性,以及对类型

的隐式转换
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));
}

答案 3 :(得分:9)

您可以使用static Dictionary<PowerupEffectType, Powerup>。我相信那将是你正在寻找的那种“婚姻”。它可以轻松枚举和访问。

答案 4 :(得分:2)

您只能使用Microsoft的文档中的数字类型。默认情况下,枚举中每个元素的基础类型是int。您可以使用冒号指定另一个整数数字类型,如上例所示。有关可能类型的完整列表,请参阅枚举。 Reference: Enumeration Types

答案 5 :(得分:2)

对不起,我不太关注这个,你到底想要实现什么;你能给出一段代码摘录吗?我不确定为什么你不能在这里使用继承以及枚举给你的类型继承没有。我觉得你在提出解决方案而不是问题,我可能完全错了,你能澄清一下你打算如何使用这个元信息吗?

我很困惑,您是否在寻找能告诉您类型/类实例类型的内容?您可以使用枚举来存储您说的每种类型的类型列表,但为什么要这样做?你说你不想让其他程序员使用switch语句,但是很抱歉我看不出你在类型的枚举中存储类型信息会带来什么好处。每个实例都知道它是什么类型以及它可以做什么。

您将如何处理类型信息?如果所有类型都继承自基类型,那么可能它们具有可以在abstract方法中为任何特殊情况处理指定的通用功能,或者可能返回Null Object无处可执行的任务(或者只是什么都不做)。这样您就不必担心添加新类 - 因为它们必须具有必要的行为。我试图避免Enum s,除非你实际上枚举一组固定的任意值,它们是不灵活的。必须保持Enum,这在实践中非常困难。

答案 6 :(得分:0)

我实际上认为你可能想看一下依赖注入框架。

看起来您正在尝试让其他开发人员处理不同的组件,然后您尝试将它们全部集成到代码库中的一个中心位置。

要看的一些项目: