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

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

所以我在xna,c 4.0中创建了一个游戏,我需要管理大量的powerups(代码中都是从类"powerup"继承的),为了处理powerups的后端管理,我目前有一个枚举powerupeffectype,它为每个子类powerup都有一个值。最后,在代码中,我需要从powerupeffectype转换为powerup类型(类Type,通常使用typeof([class name])实现)。

由于这是一个组项目,所以我希望将powerupeffectype的每个值都与其对应的类类型结合起来,也就是说:不仅希望我的其他程序员使用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。是否有任何可行的方法来保存将Type转换为上述任何数据类型并返回?

我只想说清楚,这是我希望我能做的,我正在寻找一种方法:

1
2
3
4
5
6
7
8
9
// (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%的问题上过度简化了一个解决方案?

事先谢谢!


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
}

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

1
2
3
4
5
6
7
private static Dictionary<PowerupEffectType, Type> EffectTypeMapping =
    new Dictionary<PowerupEffectType, Type>
{
    { PowerupEffectType.Lightning, typeof(LightningPowerup) },
    { PowerupEffectType.Fire, typeof(FirePowerup) },
    { PowerupEffectType.Water, typeof(WaterPowerup) }
};

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


这不是你想要的。我觉得乔恩的属性方法最好。但是为什么不用扩展方法包装它呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);
    }
}

并称之为:

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


像这样的怎么样?

使用枚举可以获得类型安全性,还可以隐式转换为类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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));
}


你可以使用static Dictionary。我相信这就是你想要的那种"婚姻"。它将允许简单的枚举和访问。


对不起,我不太明白,你到底想做什么,你能给我一个代码摘录吗?我不知道为什么你不能在这里使用继承,以及枚举给你的类型继承没有什么。我觉得你是在提出解决方案而不是问题,我可能完全错了,你能解释一下你打算如何使用这个元信息吗?

我很困惑,你是不是在要求什么东西来告诉你一个类型/类的实例的类型?您可以使用枚举来存储您所说的每种类型的类型列表,但为什么要这样做?你说你不想让其他程序员使用switch语句,但是我很抱歉,我看不出在某些枚举中存储类型信息有什么好处…类型。每个实例都知道它是什么类型,它能做什么。

您将如何处理类型信息?如果所有类型都继承自基类型,则假定它们具有可在用于任何特殊情况处理的abstract方法中指定的公共功能,或者可能返回一个Null Object,其中无需执行任何操作(或可能不执行任何操作)。这样您就不必担心添加新类了,因为它们必须具有必要的行为。我尽量避免使用Enum,除非在实际枚举一组固定的任意值的情况下,它们是不灵活的。必须维护Enums,这是非常困难的(在实践中)。


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


实际上,我认为您可能想看看依赖注入框架。

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

要查看的几个项目:

  • 网址:http://www.ninject.org/
  • http://docs.structuremap.net网站/
  • http://archive.msdn.microsoft.com/mef