2009-09-08 158 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:創建類型後無法更改。