C#动态程序集中的自引用枚举属性

时间:2009-09-08 04:54:10

标签: c# .net enums attributes

请考虑以下代码:

    [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
    }

代码编译得很好。现在我想在动态程序集中定义类似的枚举,其代码如下:

  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();

什么是“???”我传递给属性构造函数? “???”需要在我定义过程中的枚举中表示“A”字面。我已经尝试传递fb,fb.GetValue(null),并调用Enum.Parse(),Enum.ToObject(),Enum.GetValues()和其他方法的各种组合,但似乎没有任何工作。

明显替代???是基础整数枚举值(例如,A代表0,B代表1,等等),但这不是我需要它的方式。在某些时候,我想做像

这样的事情
TransitionToAttribute attr = GetCustomAttribute(...)
Type enumType = attr.Next.GetType();

并以这种方式确定枚举类型。这在第一个正常编译的例子中是可能的。但是,如果我将基础枚举值传递给动态创建的属性,则类型信息将丢失,并且enumType将报告为Int32。

2 个答案:

答案 0 :(得分:1)

在致电CreateType之前尝试致电SetCustomAttribute(请参阅SetCustomAttribute的示例代码)。

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

答案 1 :(得分:0)

你是对的,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:创建类型后无法更改。