在編寫類型提供程序時遇到了問題,我遇到了一個問題,我無法完全瞭解如何使用屬性類型的通用參數添加現有接口。如果有人知道如何將通用參數的現有接口添加到生成的類型中?向生成的類型添加接口
我想要的是生成類似於下面的類型,Bar和Foo都是生成類型。顯然,以下是一個人爲的例子。
type Bar() =
member val List: IEnumerable<Foo> with get, set
不幸的是試圖使用實現接口typeof<IEnumerable<Foo>>
一個ProvidedType時,我得到一個錯誤。我懷疑這是因爲生成的類型被用作通用參數。
異常消息是這樣的:
上項「富」的操作「模塊」不應該提供 類型,構件或參數
EDIT被稱爲:我添加簡單的代碼來重現錯誤(稱爲DefineStaticParameters):
let buildType() =
let providedType1 = ProvidedTypeDefinition("ParentType", Some typeof<obj>, IsErased = false)
let providedType2 = ProvidedTypeDefinition("DataType", Some typeof<obj>, IsErased = false)
let symbolType = ProvidedTypeBuilder.MakeGenericType(typedefof<IEnumerable<_>>, [providedType2])
let providedField = ProvidedField("propertyField", symbolType)
providedType1.AddMember(providedField)
let providedProperty = ProvidedProperty("TestProperty", symbolType)
providedProperty.GetterCode <- fun args -> Expr.FieldGet(args.[0], providedField)
providedType1.AddMember providedProperty
let pconstructor = ProvidedConstructor([ProvidedParameter("dataList", symbolType)])
pconstructor.InvokeCode <- fun args -> <@@() @@>
providedType1.AddMember pconstructor
let nestedProperty = ProvidedProperty("Data", typeof<string>)
nestedProperty.GetterCode <- fun _ -> <@@ "TEST SUCCESS" @@>
providedType2.AddMember nestedProperty
let interfaceType = ProvidedTypeBuilder.MakeGenericType(typedefof<IEquatable<_>>, [providedType2])
providedType2.AddInterfaceImplementation interfaceType
let equalsParameter = ProvidedParameter("other", providedType2)
let providedMethodEquals = ProvidedMethod("Equals", [ equalsParameter ], typeof<bool>)
providedMethodEquals.InvokeCode <- fun args ->
let propertyGet x = Expr.PropertyGet(x, nestedProperty)
let currentEq = propertyGet args.[0]
let otherEq = propertyGet args.[1]
<@@ %%currentEq = %%otherEq @@>
// Add these to the generated type with a namespace outside this method
[ providedType1; providedType2 ]
堆棧跟蹤的樣子:
在Microsoft.FSharp.Core.Operators.Raise [T](例外EXN)在 ProviderImplementation.ProvidedTypes.Misc.notRequired並[a](字符串 opname,字符串項目)ProvidedTypes.fs:線58 \在 ProviderImplementation.ProvidedTypes.ProvidedTypeDefinition.get_Module()在ProvidedTypes.fs :線1683在 System.Reflection.Emit.AssemblyBuilder.CheckContext在 System.Reflection.Emit.ModuleBuilder.GetTypeTokenWorkerNoLock(類型 (類型[]類型)類型,布爾getGenericDefinition)在 System.Reflection.Emit.ModuleBuilder.GetTypeTokenInternal(類型類型, 布爾getGenericDefinition )在 System.Reflection.Emit.SignatureHelper.AddOneArgTypeHelperWorker(類型 clsArgument,布爾lastWasGenericInst)在 System.Reflection.Emit.SignatureHelper.AddOneArgTypeHelperWorker( 類型clsArgument,布爾lastWasGenericInst)在 System.Reflection.Emit.SignatureHelper.GetType SigToken(模塊MOD, 型型)在 System.Reflection.Emit.ModuleBuilder.GetTypeTokenWorkerNoLock(類型 類型,布爾getGenericDefinition)在 System.Reflection.Emit.ModuleBuilder.GetTypeTokenInternal(類型類型, 布爾getGenericDefinition)在 系統.Reflection.Emit.TypeBuilder.AddInterfaceImplementation(Type interfaceType)
你可能會看到使用'ProvidedTypeBuilder.MakeGenericType'是否有幫助。 – kvb
它讓我更進一步,但現在我遇到了IEnumerable的提供的符號類型的問題 - 它不是在抱怨GetAttributeFlagsImpl不應該被調用。我不確定是否應該嘗試在ProvidedSymbolType上實現該方法,或者如果我在做其他問題。 –
akara
創建一個實現GetAttributeFlagsImpl的自定義SymbolType,從傳入的通用IEnumerable <>類型中獲取其類型屬性以構建它(更改ProvidedTypeBuilder.MakeGenericType捕獲此)讓我回到問題中的原始錯誤。不知道我應該如何填充Module屬性。 – akara