2

当我尝试实现通用接口时,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 属性被用作您正在实现的方法的名称,而不是函数的名称。

您如何明确设置函数名称,或者至少如何使其合法?

4

1 回答 1

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.VisualBasic.VBCodeGenerator.GenerateMethod(在一个Friend不容易被覆盖的类中)迎合.'s,用 代替它们,但忘记在 .NET 2.0-3.5 和4.0_中迎合。在 Connect 上记录一个错误可能是值得的,包括指出与正在实现的接口上的方法名称相比,方法名称应该是可单独覆盖的。`(Of <type>)

您似乎需要 的功能PrivateImplementationType来支持非通用GetEnumerator. 是我对原始代码的简单调整,以生成一个可编译的库,只有关于空代码的警告。此代码仍然存在“问题”,例如在使用method.Attributes = MemberAttributes.Private位置时被忽略PrivateImplementationType...

于 2012-10-20T09:00:45.693 回答