The CodeDom is not generating legal VB for me when I try to implement a generic interface.
Here is my VB code to generate the VB code.
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
And that will generate:
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
The problem is the name of the function. The tick mark in the function name doesn’t make for a legal function name.
It seems that when using the PrivateImplentationType property of the CodeMethodMethod the Name property gets used as the name of the method you are implementing, not the name of the function.
How do you explicitly set the function name or at least how do I get it to be something legal?
To get a compilable output, just use
ImplementationTypes: I just changed one line of your code (but I include a simple line for reference, and the correctedReturnType):There doesn’t seem to be a simple workaround using
PrivateImplementationType. Microsoft’s code inMicrosoft.VisualBasic.VBCodeGenerator.GenerateMethod(which is in aFriendclass so not easily overridden) caters for.‘s, replacing them with_, but forgets to cater for`in .NET 2.0-3.5 and(Of <type>)in 4.0. It is probably worth logging a bug at Connect, including pointing out the method name should be separately overridable compared to the method name on the interface being implemented.You seem to need the functionality of
PrivateImplementationTypeto support the non-genericGetEnumerator. Here is my simple adjustment of your original code to produce a single compilable library, with only warnings about empty code. This code still has “issues”, such as themethod.Attributes = MemberAttributes.Privatebeing ignored wherePrivateImplementationTypeis used…