Vb.net 通过CodeDom实现通用接口
当我尝试实现一个通用接口时,CodeDom并没有为我生成合法的VB 下面是我的VB代码生成的VB代码Vb.net 通过CodeDom实现通用接口,vb.net,generics,codedom,Vb.net,Generics,Codedom,当我尝试实现一个通用接口时,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.Imp
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的PrivateImplementationType属性时,Name属性被用作正在实现的方法的名称,而不是函数的名称
如何明确设置函数名,或者至少如何使其合法化?要获得可编译的输出,只需使用
ImplementationTypes
:我只更改了代码的一行(但我包含了一行供参考的简单代码,以及更正后的ReturnType
):
使用PrivateImplementationType
似乎没有简单的解决方法。Microsoft在Microsoft.VisualBasic.VBCodeGenerator.GenerateMethod
(位于Friend
类中,因此不容易重写)中的代码满足
,将其替换为
,但忘记满足.NET 2.0-3.5中的`
和4.0中的(Of)
。在Connect上记录一个bug可能是值得的,包括指出与正在实现的接口上的方法名相比,方法名应该是单独可重写的
您似乎需要
PrivateImplementationType
的功能来支持非泛型GetEnumerator
。这是我对原始代码的简单调整,以生成单个可编译库,其中只包含关于空代码的警告。此代码仍然存在“问题”,例如在使用PrivateImplementationType
时忽略method.Attributes=MemberAttributes.Private
。分配给Name属性的顺序没有影响。总结我以前(现在已删除)的注释:设置.Name
的顺序不重要;私有的GetBaseTypeOutput
无条件地在Name
前面加上前缀,但是它在.NET Framework 4中包含了对“`”c
的逻辑检查,但是这仍然会产生引用系统集合\u泛型\u IEnumerable(Of Foo)\u GetEnumerator
的错误代码!这无助于解决问题,但您的返回类型应该是“System.Collections.Generic.IEnumerator”
。非常感谢!经验教训:将非泛型类型分配给PrivateImplementationType,但将泛型类型使用ImplementationTypes.Add()。这并不像那样简单。对于非泛型类型,我也会使用ImplementationTypes
,除非我必须做一些不同的事情,就像这里的情况一样,因为我看不到如何使用VB的特性,即方法名与它正在实现的接口中的方法名不相同。
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")} _
))