我有一个类似于OP在How to load an internal class in end-user compiled code ? (advanced)中所拥有的winform,我有一个文本框,它将成为最终用户代码的来源,而且我会在按下按钮时动态编译。
以下是代码的某些部分(其中大部分是从How to load an internal class in end-user compiled code ? (advanced)复制的:
Imports System
Imports System.CodeDom.Compiler
Imports System.Reflection
Imports System.Text
Public Class Form1
Private Sub ExecuteB_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExecuteB.Click
Dim Code As String = Me.CodeToExec.Text
Dim CompilerResult As CompilerResults
CompilerResult = Compile(Code)
End Sub
Public Function Compile(ByVal Code As String) As CompilerResults
Dim CodeProvider As New VBCodeProvider
Dim CodeCompiler As System.CodeDom.Compiler.CodeDomProvider = CodeDomProvider.CreateProvider("VisualBasic")
Dim Parameters As New System.CodeDom.Compiler.CompilerParameters
Parameters.GenerateExecutable = False
Parameters.ReferencedAssemblies.Add("System.dll")
Parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll")
Parameters.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
Dim CompilerResult As CompilerResults = CodeCompiler.CompileAssemblyFromSource(Parameters, Code)
If CompilerResult.Errors.HasErrors Then
CompileTB.Clear()
For i = 0 To CompilerResult.Errors.Count - 1
CompileTB.AppendText(CompilerResult.Errors(i).ErrorText & vbCrLf)
Next
Return Nothing
Else
Return CompilerResult
End If
End Function
End Class
我的控件是:CodeToExec是用户放置自定义代码的文本框,CompileTB是列出错误的另一个文本框,ExecuteB是按钮。我的程序中还有其他类和对象,这是我想要使用的类之一:
Public Class ExceptionCriteria
Private _CriteriaName As String
Public Property CriteriaName As String
Get
CriteriaName = _CriteriaName
End Get
Set(value As String)
_CriteriaName = value
End Set
End Property
Private _RuleSet As List(Of String)
Public Property RuleSet As List(Of String)
Get
RuleSet = _RuleSet
End Get
Set(value As List(Of String))
_RuleSet = value
End Set
End Property
Private _SerializationFilePath As String
Public Property SerializationFilePath As String
Get
SerializationFilePath = _SerializationFilePath
End Get
Set(value As String)
_SerializationFilePath = value
End Set
End Property
Public Sub AddRule(newRule As String)
If IsNothing(_RuleSet) Then
_RuleSet = New List(Of String)
End If
_RuleSet.Add(newRule)
End Sub
End Class
这是我想在Form1类中使用/设置的成员之一:
Public comparisondate As Date = #2/20/2015#
我的问题是,我想访问/修改执行程序集中的对象,成员,属性,并根据那里的自定义类创建新对象。我怎么能这样做?
答案 0 :(得分:1)
我已经碰到了答案,我缺少的是
private class MyListAdapter extends ArrayAdapter<CommentInfo> {
public MyListAdapter()
{
super(Comment.this, R.layout.listview_xml, myComments);
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent)
{
itemView = convertView;
if(itemView == null)
{
itemView = getLayoutInflater().inflate(R.layout.listview_xml, parent, false);
}
CommentInfo currentComment = myComments.get(position);
TextView tvLikes = (TextView) itemView.findViewById(R.id.tvLikes);
tvLikes.setText(currentComment.likes);
ImageView ivLikes = (ImageView) itemView.findViewById(R.id.likeBtn);
ivLikes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
likePosition = position;
TextView tvlikes1 = (TextView) convertView.findViewById(R.id.tvLikes);
// Here, i will get the correct value from DB and set it.
// I am setting 999 for sample purpose
tvlikes1.setText("999");
}
});
return itemView;
}
}
然后我只需要让程序和成员共享。我希望这也能帮助像我这样的新手碰巧遇到同样的问题并通过这个页面。
答案 1 :(得分:0)
如果您想使用现有的类,您应该知道如何(自我)引用以及如何提供参数。这是一个小例子:
请勿忘记生成的代码中的Imports YourProjectName
。
示例类来做所有必要的事情
Imports System.CodeDom.Compiler
Imports System.Reflection
Public Class MyHelloCompiler
Private Shared _ass As Assembly
Private Shared _YourClass As Type
Private Shared _YourMethod As MethodInfo
Private Shared _YourClassInstance As Object
Public Sub New()
'Code to compile and instantiate the compiled class for later use:
Dim opt As New CompilerParameters _
(Nothing, String.Empty, False)
opt.GenerateExecutable = False
opt.GenerateInMemory = True
' Following is the important self reference
opt.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location)
Console.WriteLine (MyCodeToCompile)
Dim res As CompilerResults = New VBCodeProvider().CompileAssemblyFromSource (opt, MyCodeToCompile)
_ass = res.CompiledAssembly
_YourClass = _ass.GetType ("MyExampleClass")
_YourMethod = _YourClass.GetMethod ("MyExampleProperty")
_YourClassInstance = Activator.CreateInstance ( _YourClass)
End Sub
Public Class MyExampleClass()
Public Property MyExampleProperty as String
End Class
Public Function RunCompiledCodeWithParams( _
instanceOfExampleClass as MyExampleClass) as String
Dim params As Object() = New Object() {instanceOfExampleClass}
Return CStr(_YourMethod.Invoke(_YourClassInstance, params))
End Function
Private Function MyCodeToCompile() as String
Return _
"Imports System" & vbCrLf & _
"Imports YourProjectName" & vbCrLf & _
"Public Class ClassToCompile" & vbCrLf & _
" Public Shared Function GetExampleProperty(prmExampleClassInstance as MyExampleClass) as String" & vbcrlf & _
" Return prmExampleClassInstance.MyExampleProperty" & vbcrlf & _
" End Function" & vbcrlf & _
"End Class"
End Function
End Class
调用上述内容:
'....
Dim MyTestCompile As MyHelloCompiler = New MyHelloCompiler
Dim MyDummyClass As MyExampleClass = New MyExampleClass
MyDummyClass.MyExampleProperty = "I am the property value"
Dim MyResult as String = _
MyTestCompile.RunCompiledCodeWithParams(MyDummyClass)
'....