C# GenerateCodeFromCompileUnit 正在生成带有特殊字符的代码 [Microsoft.CSharp.CSharpCodeProvider]
C# GenerateCodeFromCompileUnit is Generating Code with Special Characters [Microsoft.CSharp.CSharpCodeProvider]
我正在使用 GenerateCodeFromCompileUnit
和 IndentedTextWriter
从 C#
源文件生成代码。这样做我可以生成一个 .cs
文件。但是我看到在每个声明的变量和函数 Return 类型之前插入了一个特殊字符 @
。这是我的代码。
我正在使用 Class
来保存要插入的函数详细信息。
Dim provider As Microsoft.CSharp.CSharpCodeProvider
Dim options = New System.CodeDom.Compiler.CompilerParameters
options.ReferencedAssemblies.Add("System.dll")
options.GenerateExecutable = False
options.GenerateInMemory = True
options.IncludeDebugInformation = True
options.OutputAssembly = "FunctionEvaluated.dll"
Dim compileUnit As System.CodeDom.CodeCompileUnit
compileUnit = New CodeDom.CodeCompileUnit
Dim codeNamespace = New CodeDom.CodeNamespace("NewNamespace")
compileUnit.Namespaces.Add(codeNamespace)
Dim classForCompile = New CodeDom.CodeTypeDeclaration("NewAction")
codeNamespace.Types.Add(classForCompile)
Dim functionToEvaluate = New CodeDom.CodeMemberMethod()
Dim returnType As CodeDom.CodeTypeReference
If functionClass.FunctionNameAndType.Select(Function(fn) fn.Value)(0).ToString() = "void" Then
returnType = New CodeDom.CodeTypeReference("void")
Else
returnType = New CodeDom.CodeTypeReference(functionClass.FunctionNameAndType.Select(Function(fn) fn.Value)(0).ToString())
End If
Dim parameterExpressionCollection = New CodeDom.CodeParameterDeclarationExpressionCollection()
For Each ip In functionClass.FunctionNameIP
For Each fnIP In ip.Value
Dim parameterExpression As CodeDom.CodeParameterDeclarationExpression
parameterExpression = New CodeDom.CodeParameterDeclarationExpression(fnIP.Value.ToString(), fnIP.Key.ToString())
parameterExpressionCollection.Add(parameterExpression)
Next
Next
functionToEvaluate.Name = functionClass.FunctionNameAndType.Select(Function(fn) fn.Key)(0).ToString()
functionToEvaluate.ReturnType = returnType
functionToEvaluate.Parameters.AddRange(parameterExpressionCollection)
classForCompile.Members.Add(functionToEvaluate)
provider = New Microsoft.CSharp.CSharpCodeProvider
Dim sourceFile As String
sourceFile = "FunctionEvaluated.cs"
Dim tw As IndentedTextWriter = New IndentedTextWriter(New StreamWriter(sourceFile, False), vbTab)
provider.GenerateCodeFromCompileUnit(compileUnit, tw, New CodeGeneratorOptions())
tw.Close()
输出
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace NewNamespace {
public class NewAction {
private @int functionAdd(@int b, @int a) {
}
}
}
我相信你的问题出在行上
New CodeDom.CodeTypeReference(functionClass.FunctionNameAndType.Select(Function(fn) fn.Value)(0).ToString())
和
parameterExpression = New CodeDom.CodeParameterDeclarationExpression(fnIP.Value.ToString(), fnIP.Key.ToString())
我怀疑使用字符串指定本机类型导致 DOM 认为这是用户定义的类型 'int' 并用 @ 屏蔽它以防止本机 int
从被使用。来自 https://en.wikipedia.org/wiki/C_Sharp_syntax#Keywords
If an identifier is needed which would be the same as a reserved keyword, it may be prefixed by the @ character to distinguish it
要确保输出使用像 int
这样的本机类型,您可以尝试使用
new CodeTypeReference(typeof(int))
换句话说,使用真正的 Type
和 public CodeTypeReference(Type type);
构造函数。
要从命名类型的字符串中获取实际类型,您可以使用 Type.GetType(String)
函数。
所以试试这个:
New CodeDom.CodeTypeReference(Type.GetType(functionClass.FunctionNameAndType.Select(Function(fn) fn.Value)(0).ToString()))
和
parameterExpression = New CodeDom.CodeParameterDeclarationExpression(Type.GetType(fnIP.Value.ToString()), fnIP.Key.ToString())
我正在使用 GenerateCodeFromCompileUnit
和 IndentedTextWriter
从 C#
源文件生成代码。这样做我可以生成一个 .cs
文件。但是我看到在每个声明的变量和函数 Return 类型之前插入了一个特殊字符 @
。这是我的代码。
我正在使用 Class
来保存要插入的函数详细信息。
Dim provider As Microsoft.CSharp.CSharpCodeProvider
Dim options = New System.CodeDom.Compiler.CompilerParameters
options.ReferencedAssemblies.Add("System.dll")
options.GenerateExecutable = False
options.GenerateInMemory = True
options.IncludeDebugInformation = True
options.OutputAssembly = "FunctionEvaluated.dll"
Dim compileUnit As System.CodeDom.CodeCompileUnit
compileUnit = New CodeDom.CodeCompileUnit
Dim codeNamespace = New CodeDom.CodeNamespace("NewNamespace")
compileUnit.Namespaces.Add(codeNamespace)
Dim classForCompile = New CodeDom.CodeTypeDeclaration("NewAction")
codeNamespace.Types.Add(classForCompile)
Dim functionToEvaluate = New CodeDom.CodeMemberMethod()
Dim returnType As CodeDom.CodeTypeReference
If functionClass.FunctionNameAndType.Select(Function(fn) fn.Value)(0).ToString() = "void" Then
returnType = New CodeDom.CodeTypeReference("void")
Else
returnType = New CodeDom.CodeTypeReference(functionClass.FunctionNameAndType.Select(Function(fn) fn.Value)(0).ToString())
End If
Dim parameterExpressionCollection = New CodeDom.CodeParameterDeclarationExpressionCollection()
For Each ip In functionClass.FunctionNameIP
For Each fnIP In ip.Value
Dim parameterExpression As CodeDom.CodeParameterDeclarationExpression
parameterExpression = New CodeDom.CodeParameterDeclarationExpression(fnIP.Value.ToString(), fnIP.Key.ToString())
parameterExpressionCollection.Add(parameterExpression)
Next
Next
functionToEvaluate.Name = functionClass.FunctionNameAndType.Select(Function(fn) fn.Key)(0).ToString()
functionToEvaluate.ReturnType = returnType
functionToEvaluate.Parameters.AddRange(parameterExpressionCollection)
classForCompile.Members.Add(functionToEvaluate)
provider = New Microsoft.CSharp.CSharpCodeProvider
Dim sourceFile As String
sourceFile = "FunctionEvaluated.cs"
Dim tw As IndentedTextWriter = New IndentedTextWriter(New StreamWriter(sourceFile, False), vbTab)
provider.GenerateCodeFromCompileUnit(compileUnit, tw, New CodeGeneratorOptions())
tw.Close()
输出
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace NewNamespace {
public class NewAction {
private @int functionAdd(@int b, @int a) {
}
}
}
我相信你的问题出在行上
New CodeDom.CodeTypeReference(functionClass.FunctionNameAndType.Select(Function(fn) fn.Value)(0).ToString())
和
parameterExpression = New CodeDom.CodeParameterDeclarationExpression(fnIP.Value.ToString(), fnIP.Key.ToString())
我怀疑使用字符串指定本机类型导致 DOM 认为这是用户定义的类型 'int' 并用 @ 屏蔽它以防止本机 int
从被使用。来自 https://en.wikipedia.org/wiki/C_Sharp_syntax#Keywords
If an identifier is needed which would be the same as a reserved keyword, it may be prefixed by the @ character to distinguish it
要确保输出使用像 int
这样的本机类型,您可以尝试使用
new CodeTypeReference(typeof(int))
换句话说,使用真正的 Type
和 public CodeTypeReference(Type type);
构造函数。
要从命名类型的字符串中获取实际类型,您可以使用 Type.GetType(String)
函数。
所以试试这个:
New CodeDom.CodeTypeReference(Type.GetType(functionClass.FunctionNameAndType.Select(Function(fn) fn.Value)(0).ToString()))
和
parameterExpression = New CodeDom.CodeParameterDeclarationExpression(Type.GetType(fnIP.Value.ToString()), fnIP.Key.ToString())