当我尝试实现通用接口时,CodeDom没有为我生成合法的VB。
这是我生成VB代码的VB代码。
Private Sub RunTest()
Dim compileUnit = New CodeCompileUnit
Dim ns As New CodeNamespace()
compileUnit.Namespaces.Add(ns)
ns.Imports.Add(New CodeNamespaceImport("System"))
ns.Imports.Add(New CodeNamespaceImport("System.Collections.Generic"))
Dim fooCollection = New CodeTypeDeclaration("FooCollection")
ns.Types.Add(fooCollection)
fooCollection.TypeAttributes = Reflection.TypeAttributes.Public
fooCollection.IsClass = True
fooCollection.BaseTypes.Add(New CodeTypeReference(GetType(System.Object)))
fooCollection.BaseTypes.Add(New CodeTypeReference( _
"System.Collections.Generic.IEnumerable" _
, New CodeTypeReference() {New CodeTypeReference("Foo")} _
))
Dim method = New CodeMemberMethod
fooCollection.Members.Add(method)
method.Attributes = MemberAttributes.Private
method.Name = "GetEnumerator"
method.ReturnType = New CodeTypeReference( _
"System.Collections.Generic.IEnumerable" _
, New CodeTypeReference() {New CodeTypeReference("Foo")} _
)
method.PrivateImplementationType = New CodeTypeReference( _
"System.Collections.Generic.IEnumerable" _
, New CodeTypeReference() {New CodeTypeReference("Foo")} _
)
Dim provider = New Microsoft.VisualBasic.VBCodeProvider
Dim options = New Compiler.CodeGeneratorOptions
Dim writer = New IO.StringWriter
provider.GenerateCodeFromCompileUnit(compileUnit, writer, options)
Console.WriteLine(writer.ToString)
End Sub
这会产生:
Public Class FooCollection
Inherits Object
Implements System.Collections.Generic.IEnumerable(Of Foo)
Function System_Collections_Generic_IEnumerable`1_GetEnumerator() _
As System.Collections.Generic.IEnumerable(Of Foo) _
Implements System.Collections.Generic.IEnumerable(Of Foo).GetEnumerator
End Function
End Class
问题是函数的名称。函数名称中的刻度标记不适用于合法的函数名称。
似乎在使用CodeMethodMethod的PrivateImplentationType属性时,Name属性将被用作您正在实现的方法的名称,而不是函数的名称。
您如何明确设置功能名称,或者至少如何使其成为合法的?
答案 0 :(得分:2)
要获得可编辑的输出,只需使用ImplementationTypes
:我刚刚更改了一行代码(但我提供了一条简单的参考线以及更正后的ReturnType
):
method.Name = "GetEnumerator"
method.ReturnType = New CodeTypeReference( _
"System.Collections.Generic.IEnumerator" _
, New CodeTypeReference() {New CodeTypeReference("Foo")} _
)
method.ImplementationTypes.Add(New CodeTypeReference( _
"System.Collections.Generic.IEnumerable" _
, New CodeTypeReference() {New CodeTypeReference("Foo")} _
))
使用PrivateImplementationType
似乎没有简单的解决方法。 Microsoft Microsoft.VisualBasic.VBCodeGenerator.GenerateMethod
中的代码(位于Friend
类中,因此不容易被覆盖)适用于.
,并将其替换为_
,但忘记了`
.NET 2.0-3.5中的1}}和4.0中的(Of <type>)
。可能值得在Connect上记录一个错误,包括指出方法名称应该与正在实现的接口上的方法名称相比可以单独覆盖。
您似乎需要PrivateImplementationType
的功能来支持非通用GetEnumerator
。 Here是我对原始代码的简单调整,以生成单个可编译库,仅显示有关空代码的警告。此代码仍有“问题”,例如method.Attributes = MemberAttributes.Private
在使用PrivateImplementationType
时被忽略...