我有一个允许用户编写插件的项目。我包含一个允许在C#和VB.NET中编写代码并使用CodeDom编译器编译它的小型IDE。每个插件都继承了一个特定的基类。
为了让用户的生活更轻松,我提供了各种插件类型的基本模板。基本上当用户创建一个XY类型的新插件时,他从一个类似于你写的时候的基本实现开始
Public Class Foo
Inherits BaseFoo
并在Visual Studio中按Enter键。 不酷的是,我刚刚将一些包含预制代码的文本文件添加到资源中并从那里显示它。这种方法很有效,直到对基类的定义进行更改,因为需要相应地调整预制代码。
在框架中,存在从CodeDomProvider
派生的类,如Microsoft.VisualBasic.VBCodeGenerator
,它们似乎包含基于类型定义创建代码的必要方法。但是,CodeDom
方法似乎旨在从头开始创建新类型,例如用于编写脚本,并且在某种意义上与Reflection
无法很好地交互,我无法提供MethodInfos
等等直接到CodeDom。
我可能会在一起手动构建要生成的类型,例如
Dim v As New Microsoft.VisualBasic.VBCodeProvider
Dim t As New CodeDom.CodeTypeDeclaration("Foo")
t.Attributes = CodeDom.MemberAttributes.Public
Dim r As New CodeDom.CodeTypeReference(GetType(Foo))
t.BaseTypes.Add(r)
t.IsClass = True
t.Name = "TestClass"
Dim base = GetType(Foo)
For Each method In base.GetMethods
If (method.Attributes And Reflection.MethodAttributes.Abstract) > 0 Then
Dim m As New CodeDom.CodeMemberMethod()
For Each p In method.GetParameters
Dim newp As New CodeDom.CodeParameterDeclarationExpression(p.ParameterType, p.Name)
newp.Direction = If(p.IsIn, CodeDom.FieldDirection.In, CodeDom.FieldDirection.Out)
m.Parameters.Add(newp)
Next
m.Name = method.Name
m.Attributes = CodeDom.MemberAttributes.Public Or CodeDom.MemberAttributes.Override
t.Members.Add(m)
End If
Next
Dim w As New IO.StringWriter
Dim opts As New CodeDom.Compiler.CodeGeneratorOptions
v.GenerateCodeFromType(t, w, opts)
对于示例类
Public MustInherit Class Foo
Public Property Foo1 As Double
Public Function What() As Double
Return Double.NaN
End Function
Public MustOverride Sub Test(ByRef Was As Double)
Public MustOverride ReadOnly Property Something As Double
End Class
这会创建输出
Public Class TestClass
Inherits TypeGenerator.Foo
Public Overrides Sub Test(ByRef Was As System.Double&)
End Sub
Public Overrides Sub get_Something()
End Sub
End Class
这是正确的方向,但它似乎很容易出错和非常繁琐。 (在旁注中,为什么它将参数实现为System.Double&
甚至不编译?作为ByVal
参数,它可以工作。)
有没有更简单的方法来实现我的需求?