简体   繁体   中英

Typesafe enum or attribute enum?

My first approach looked like it would work very nicely until I got a runtime error I had no idea how to solve at var name = ((LCData)attributes[0]).Name; about index out of range. Practically I was just copying the code I found at Getting attributes of Enum's value so I was not 100% sure what it actually did. So when the following code didn't work, I moved on to another solution.

public enum Identification : ushort

{

    [LCAttribute("IMG_BG01_Greens")]
    BG01_Greens = 0,

    [LCAttribute("Rabbit", "IMG_E01_Rabbit")]
    ENEMY_E01_Rabbit = 2000,
}

public static class Enums
{
    public static LCData GetInfo(Identification id)
    {
        var type = typeof(Identification);
        var memInfo = type.GetMember(id.ToString());
        var attributes = memInfo[0].GetCustomAttributes(typeof(LCData), false);
        var name = ((LCData)attributes[0]).Name;
        var tex = ((LCData)attributes[0]).Texture;

        LCData data;
        data.Name = name;
        data.Texture = tex;
        return data;
    }
}

public struct LCData
{
    public string Name;
    public string Texture;

    public LCData(Identification id)
    {
        this = Enums.GetInfo(id);
    }
}

public class LCAttribute : System.Attribute
{
    private string _Name;
    public string Name
    {
        get
        {
            return _Name;
        }
    }

    private string _Texture;
    public string Texture
    {
        get
        {
            return _Texture;
        }
    }

    public LCAttribute(string texture)
    {
        _Texture = texture;
    }

    public LCAttribute(string name, string texture)
    {
        _Name = name;
        _Texture = texture;
    }
}

Secondly I tried the typesafe enum approach. This had 2 fatal weaknesses I couldn't find a solution for:

1) I cannot get a list of available enum entries for looping operations.

2) I cannot get the corresponding enum entry by an id number.

public sealed class Identification
{

    private readonly ushort _ID;
    private readonly string _Name;
    private readonly string _Tex;

    public static readonly Identification BG01_Greens = new Identification(0, "IMG_BG01_Greens");
    public static readonly Identification ENEMY_E01_Rabbit = new Identification(2000, "Rabbit", "IMG_E01_Rabbit");

    private Identification(ushort id, string tex)
    {
        _ID = id;
        _Tex = tex;
    }

    private Identification(ushort id, string name, string tex)
    {
        _ID = id;
        _Name = name;
        _Tex = tex;
    }
    public ushort ID { get { return _ID; } }
    public string Name { get { return _Name; } }
    public string Texture { get { return _Tex; } }
}

How should I proceed? Why doesn't my first solution work?

You are confusing LCData and LCAttriubte . Because LCAttribute is a valid attribute, but you are trying to use LCData as the attribute. (By the way, probably you don't need two separate types... but I bear with you ).

This the ammended code:

public enum Identification : ushort
{
    [LCAttribute("IMG_BG01_Greens")] //Look the type of the attributes is LCAttribute
    BG01_Greens = 0,

    [LCAttribute("Rabbit", "IMG_E01_Rabbit")]
    ENEMY_E01_Rabbit = 2000,
}

public static class Enums
{
    public static LCData GetInfo(Identification id)
    {
        var type = typeof(Identification);
        var memInfo = type.GetMember(id.ToString());
        //this will return an array of LCAttributes
        var attributes = memInfo[0].GetCustomAttributes(typeof(LCAttribute), false);
        //I tell you they are LCAttribute not LCData
        var name = ((LCAttribute)attributes[0]).Name;
        var tex = ((LCAttribute)attributes[0]).Texture;
        //If the above were an LCData why would create a new one here? [Rethorical]
        LCData data;
        data.Name = name;
        data.Texture = tex;
        return data;
    }
}

Note: For altenatives approaches and maybe some insight into this approach you can see my answer to How do you make an 'enum' that has data tied to it? . The approach you use here is listed under "Custom Attributes".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM