2

I did a custom attribute for fields that receives a string. Then I'm using the custom attribute in an enum. I need to get the result of "MyMethod" from FieldAttribute, but It doesn't return the string,

Here's what I have:

Enum and attribute:

public enum CustomEnum
{
    [Field("first field")]
    Field1,
    [Field("second field")]
    Field2,
    [Field("third field")]
    Field3
}

[AttributeUsage(AttributeTargets.Field)]
public class FieldAttribute : Attribute
{
    private string name;

    public FieldAttribute(string name)
    {
        this.name = name;
    }

    public string LastName { get; set; }

    public string MyMethod()
    {
        return this.name + this.LastName;
    }
}

Usage:

public class Program
{
    public static void Main(string[] args)
    {
        PrintInfo(typeof(CustomEnum));
    }

    public static void PrintInfo(Type t)
    {
        Console.WriteLine($"Information for {t}");
        Attribute[] attrs = Attribute.GetCustomAttributes(t);

        foreach (Attribute attr in attrs)
        {
            if (attr is FieldAttribute)
            {
                FieldAttribute a = (FieldAttribute)attr;
                Console.WriteLine($"   {a.MyMethod()}");
            }
        }
    }
}

Some help please!!!

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Westbrook
  • 21
  • 3
  • Possible duplicate of [Getting attributes of Enum's value](https://stackoverflow.com/questions/1799370/getting-attributes-of-enums-value) – Wai Ha Lee Feb 19 '19 at 17:17

1 Answers1

2

It works like this:

public static void PrintInfo(Type t)
{
    Console.WriteLine($"Information for {t}");

    var pairs =
        from name in t.GetEnumNames()
        let member = t.GetMember(name).Single()
        let attr = (FieldAttribute)member.GetCustomAttributes(typeof(FieldAttribute), false)
                      .SingleOrDefault()
        let text = attr.MyMethod()
        select (name, text);

    foreach (var (name, text) in pairs)
        Console.WriteLine($"{name} -> {text}");
}

Explanation: you are using GetCustomAttributes on the type, but you need actually the enum constants which are indeed fields on the enum type. So you need to get the MemberInfo for the enum constant and ask for its attribute.


For a really old compiler you can use a simple

public static void PrintInfo(Type t)
{
    Console.WriteLine($"Information for {t}");

    foreach (string name in t.GetEnumNames())
    {
        MemberInfo member = t.GetMember(name).Single();
        FieldAttribute attr =
            (FieldAttribute)member.GetCustomAttributes(typeof(FieldAttribute), false)
                      .SingleOrDefault();
        string text = attr.MyMethod();
        Console.WriteLine(name + " -> " + text);
    }
}
Vlad
  • 35,022
  • 6
  • 77
  • 199
  • What's "name" and "text" in select (name, text); Severity Code Description Project File Line Suppression State Error CS8130 Cannot infer the type of implicitly-typed deconstruction variable 'name'. I got this error – Westbrook Feb 19 '19 at 15:38
  • @Westbrook: `name` is defined on `from name in names`, `text` in `let text = attr.MyMethod()` – Vlad Feb 19 '19 at 15:40
  • It doesn't work :( Severity Code Description Project File Line Suppression State Error CS8130 Cannot infer the type of implicitly-typed deconstruction variable 'name'. – Westbrook Feb 19 '19 at 16:07
  • @Westbrook: Which VIsual Studio version / language version do you use? – Vlad Feb 19 '19 at 16:10
  • 1
    a quick hack might be: `foreach (var pair in pairs) Console.WriteLine(pair.name + " -> " + pair.text);`, but for a down-level compiler, it might need more love - perhaps switching to `select new { name, text };` – Marc Gravell Feb 19 '19 at 16:15