Self-referential enum attributes in C # dynamic assembly

Consider the following code:

    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Enum, AllowMultiple = true)]
    public class TransitionToAttribute : Attribute
    {
      public readonly object Next;
      public TransitionToAttribute(object next)
      {
        Next = next;
      }
    }

    [TransitionToAttribute(DirectedGraph.A)]
    public enum DirectedGraph
    {
      [TransitionToAttribute(DirectedGraph.B)]
      A,

      [TransitionToAttribute(null)]
      B
    }

The code compiles fine. Now I want to define a similar enumeration in a dynamic assembly with code like:

  AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(
    new AssemblyName("TestAssembly"), AssemblyBuilderAccess.RunAndSave);
  ModuleBuilder mb = ab.DefineDynamicModule("TestModule");
  EnumBuilder eb = mb.DefineEnum("DirectedGraph2", TypeAttributes.Public, typeof(int));
  FieldBuilder fb = eb.DefineLiteral("A", 0);
  FieldBuilder fb2 = eb.DefineLiteral("B", 1);
  eb.SetCustomAttribute(new CustomAttributeBuilder(
    typeof(TransitionToAttribute).GetConstructors().First(), new object[] { ??? }));
  Type created = eb.CreateType();

What "???" what am I going to attribute constructor? "???" there should be some representation of the literal “A” in the listing, which I find in the definition process. I tried passing fb, fb.GetValue (null) and calling various combinations of Enum.Parse (), Enum.ToObject (), Enum.GetValues ​​() and other methods, but nothing works.

Obvious replacement for ??? is the base integer value of the enumeration (e.g. 0 for A, 1 for B, etc.), but it does not work the way I need it. At some point I want to do something like

TransitionToAttribute attr = GetCustomAttribute(...)
Type enumType = attr.Next.GetType();

. , . enum , , enumType Int32.

+3
2

CreateType SetCustomAttribute (. SetCustomAttribute).

Type created = eb.CreateType();
eb.SetCustomAttribute(new CustomAttributeBuilder(
    typeof(TransitionToAttribute).GetConstructors().First(),
    new object[] { Enum.Parse(created, "A") }));
+1

, ESRogs, . (fb).

  Type created = eb.CreateType();
  eb.SetCustomAttribute(new CustomAttributeBuilder(
    typeof(TransitionToAttribute).GetConstructors().First(),
    new object[] { Enum.Parse(created, "A") }));
  fb.SetCustomAttribute(new CustomAttributeBuilder(
    typeof(TransitionToAttribute).GetConstructors().First(),
    new object[] { Enum.Parse(created, "A") }));

SetCustomAttribute . InvalidOperationException: , .

0
source

Source: https://habr.com/ru/post/1717112/


All Articles