2009-09-08 118 views
3

考虑下面的代码:自引用属性的枚举在C#动态组件

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

回答

1

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

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

你说得对,ESRogs,用于在枚举上设置属性。但我也需要在enum文字(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:创建类型后无法更改。