我目前正在开发一个应用程序,您可以使用它创建"程序"而无需编写源代码,只需单击并播放即可.
现在的问题是如何从我的数据模型生成可执行程序.有很多可能性,但我不确定哪一个对我最好.我需要生成具有类和命名空间的程序集以及可以作为应用程序一部分的所有内容.
CodeDOM类:我听说过这个类的很多限制和错误.我需要在方法参数和返回值上创建属性.这支持吗?
以编程方式创建C#源代码然后在其上调用CompileAssemblyFromFile:这可以工作,因为我可以生成我想要的任何代码,C#支持大多数CLR功能.但这不会很慢吗?
使用反射ILGenerator类:我认为我可以生成所有可能的.NET代码.但我认为这比其他方法更复杂,更容易出错?
有其他可能的解决方案吗?
编辑:该工具是开发应用程序的一般工具,它不限于特定的域.我不知道它是否可以被视为可视化编程语言.用户可以创建类,方法,方法调用,各种表达式.它不会非常有限,因为您应该能够完成实际编程语言中允许的大多数事情.目前,用户仍然必须将很多东西写成文本,但最终的目标是,几乎所有东西都可以一起点击.
internal List<CodeMemberMethod> createEventHooks()
{
string[] eventNames = new string[] { "OnUpdate", "OnInsert", "OnDelete", "OnSelect", "OnSelectAll" };
List<CodeMemberMethod> eventHooks = new List<CodeMemberMethod>();
foreach (string eventName in eventNames)
{
CodeMemberMethod eventHook = new CodeMemberMethod();
eventHook.Name = eventName;
eventHook.Attributes = MemberAttributes.ScopeMask;
eventHook.ReturnType = new CodeTypeReference("partial void");
}
return eventHooks;
}
Run Code Online (Sandbox Code Playgroud)
正在生成以下代码:
partial void OnUpdate() {
}
partial void OnInsert() {
}
partial void OnDelete() {
}
partial void OnSelect() {
}
partial void OnSelectAll() {
}
Run Code Online (Sandbox Code Playgroud)
如何让CodeDom删除" {}",这将解决我正在尝试编译的编译器错误?我想过只使用一个CodeSnippetStatement(我宁愿不这样做,因为这首先打破了使用CodeDom的目的),但我找不到CodeTypeDeclaration类中添加片段的地方. …
有没有人知道Java的工具(类似于C#的codedom),它提供了一种生成.java文件的Java代码的方法?
编辑:我正在建立一个平台,其主要目标是自动化操作.提供一些输入,我想为外部工具生成代码.所以它不是运行时生成的.我想生成并输出到实际文件.
有没有办法从VB代码中删除Codedom中生成的代码中的项目?
例如,在我生成的所有代码的顶部,它具有:
'------------------------------------------------------------------------------ ' ' This code was generated by a tool. ' Runtime Version:4.0.30319.1 ' ' Changes to this file may cause incorrect behavior and will be lost if ' the code is regenerated. ' '------------------------------------------------------------------------------ Option Strict Off Option Explicit On
我希望这两个都消失 - 评论文本和两者Option xxx.我试过玩弄CodeGeneratorOptions,但一直无法从生成的代码中删除上述内容.
CodeDom可以在生成ac#方法时创建可选参数并提供默认值吗?
例如:
public void ExampleMethod(int required
, string optionalstr = "default string"
, int optionalint = 10)
Run Code Online (Sandbox Code Playgroud)
解决方案 我找到了一个简单的解决方法,您可以将默认值作为参数名称的一部分:
CodeParameterDeclarationExpression(typeof(int), "optionalint = 5");
Run Code Online (Sandbox Code Playgroud)
这适用于我b/c我只使用CodeDom来生成C#代码.如果您需要支持多种语言,它将无法工作.
好吧,所以我对所有条款和内容都不满意,但这是我迄今为止所创造的内容:
1:一个应用程序,逐个字符地读取源代码文件的内容.和;
2:确定字符/字符串'x'是标识符,整数还是其他内容的应用程序.
和3:另一个将它们放在一起的应用程序,并创建另一个文件,基本上包含要发送到我的第4个应用程序的指令,基本上是这样的:
将Integer oldValue的值分配给Integer newValue.
所以,然后我的第四个应用程序接收到这个指令,并"编译"它(好吧,在这种情况下,我会说我只想解释它),然后创建一个应用程序:
int newValue = oldValue;
Run Code Online (Sandbox Code Playgroud)
因此,由于我已经完成了解析器等,我如何将我的指令转换为导致实际操作的指令,并生成一个EXE文件,所以当我双击该文件时,它将执行上述操作?
我希望这不会让你感到困惑.
所以,基本上,我想我要问的是:"我如何以编程方式从字符串创建"事件",将其保存到文件并生成exe?"
继续这个优秀的答案,我想知道使用dynamic关键字的DLR是否允许更简洁的方式为生成的程序集编写代码.
例如,上述答案的代码可以:
using (Microsoft.CSharp.CSharpCodeProvider foo =
new Microsoft.CSharp.CSharpCodeProvider())
{
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters() {
GenerateInMemory = true
},
"public class FooClass { public string Execute() { return \"output!\";}}"
);
var type = res.CompiledAssembly.GetType("FooClass");
var obj = Activator.CreateInstance(type);
var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
}
Run Code Online (Sandbox Code Playgroud)
变成这样的东西:
using (Microsoft.CSharp.CSharpCodeProvider foo =
new Microsoft.CSharp.CSharpCodeProvider())
{
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters() {
GenerateInMemory = true
},
"public class FooClass { public string Execute() { return …Run Code Online (Sandbox Code Playgroud) 我需要初始化我的对象,如下所示:
var obj = new EduBranch {
Id = model.Id,
WorklevelId = model.WorklevelId,
EdulevelId = model.EdulevelId,
Title = model.Title,
StartEduYearId = model.StartEduYearId,
EndEduYearId = model.EndEduYearId,
};
Run Code Online (Sandbox Code Playgroud)
但在CodeDOM中,我只能找到:
var objectCreate1 = new CodeObjectCreateExpression("EduBranch",
new CodeExpression[]{});
Run Code Online (Sandbox Code Playgroud)
这是使用括号来初始化而不是括号.是否有CodeDOM方法?(我已经使用stringBuilder创建了我的代码,但我正在寻找CodeDOM方法)谢谢
比方说,我有以下简化类型:
public class Model
{
public decimal? Result { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如何使用CodeDOM表示空合并运算符来生成C#代码,它有可能吗?现在我正在使用以下解决方法:
new CodePropertyReferenceExpression(
new CodePropertyReferenceExpression(modelArgument, "Result"),
"Value"))
Run Code Online (Sandbox Code Playgroud)
这等于model.Result.Value,但不是model.Result ?? 0M
CodeExpressionequalent到model.Result.GetValueOrDefault(0M)适合于空值类型
new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
new CodePropertyReferenceExpression(modelArgument, "Result"),
"GetValueOrDefault"),
new [] { new CodePrimitiveExpression(0m) })),
Run Code Online (Sandbox Code Playgroud) 我目前正在将旧应用程序从 .Net Framework 4.5.2 升级到 .Net 6。该应用程序当前通过 CodeDom 编译代码,然后执行。在 .Net 6 中,不再支持通过 CodeDom 进行编译,因此我一直在转换代码以改为使用 Microsoft.CodeAnalysis (Roslyn)。我已经成功地在 .Net 6 中编译了代码并消除了所有错误和警告。
我无法弄清楚如何从编译代码外部存在的对象为编译代码中的字段设置值。
在CodeDom中,您可以使用System.Reflection.FieldInfo和compiledCode.GetType("Script").GetField("app")来获取字段。然后使用.SetValue 设置值。到目前为止,我还没有找到 Roslyn 的等效命令。
下面是一个有效的 CodeDom 代码示例。“app”是要设置值的字段。
'CodeDom example
'Add referenced assemblies
Dim compileParams As System.CodeDom.Compiler.CompilerParameters = New CompilerParameters
compileParams.ReferencedAssemblies.Add("system.dll")
compileParams.ReferencedAssemblies.Add("system.xml.dll")
compileParams.ReferencedAssemblies.Add("system.data.dll")
compileParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
compileParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.Compatibility.dll")
compileParams.ReferencedAssemblies.Add("mscorlib.dll")
compileParams.ReferencedAssemblies.Add(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location) & "\CustomDLL.dll")
compileParams.CompilerOptions = "/t:library"
compileParams.GenerateInMemory = True
compileParams.GenerateExecutable = False
'Script example. Formatted for readability.
Dim sb As StringBuilder = New StringBuilder
sb.Append(
"Option Strict Off
Option Explicit On
Imports System
Imports System.XML …Run Code Online (Sandbox Code Playgroud)