昨天在InfoWorld上关于新微软Roslyn的新闻稿中:
这种"解构"编译器最明显的优点是它允许从.Net应用程序内部调用整个编译执行过程.Hejlsberg演示了一个C#程序,它将一些代码片段作为字符串传递给C#编译器; 编译器将生成的IL汇编代码作为对象返回,然后将其传递到公共语言运行库(CLR)以供执行.瞧!使用Roslyn,C#获得了动态语言在运行时生成和调用代码的能力.
自从.NET 4发布以来,我已经能够做到这一点CSharpCodeProvider.CompileAssemblyFromSource,实际上我在之前编写的一个ASP.Net项目中使用它实际上就是这样 - 允许用户在文本框中键入代码,选择程序集/名称空间引用,然后执行并显示该代码的输出,以便在Windows Azure上进行实时环境代码测试.
是CodeDomRoslyn的一部分/前身吗?罗斯林的特殊好处是CodeDom什么?
用于VC++的Visual Studio IntelliSense包括"完整的" EDG C++解析器(也被英特尔和其他人使用).由于插件可以访问C#Code DOM(如果我错了,请纠正我),C++ Code DOM是否也可以访问?这可以用于分析VS环境中的开放VC++项目吗?
使用Reflection.Emit库与CodeDOM在运行时动态生成代码有什么优缺点?
我试图在基于XML格式运行时可用元数据的系统中生成一些(相对复杂的)动态类.我将生成扩展应用程序集中现有类的类,实现其他接口,添加方法以及覆盖虚拟和抽象成员.
我想确保在深入实现之前选择适当的技术.有关这些不同代码生成技术如何不同的任何信息都会有所帮助.此外,任何有关简化或简化工作的开源库的信息都将是有用的.
CodeDomProvider objCodeCompiler = CodeDomProvider.CreateProvider( "CSharp" );
CompilerParameters objCompilerParameters = new CompilerParameters();
...
CompilerResults objCompileResults = objCodeCompiler.CompileAssemblyFromFile( objCompilerParameters, files.ToArray() );
Run Code Online (Sandbox Code Playgroud)
当我编译我的文件时,我得到:
FileFunctions.cs(347):错误:意外字符'$'
有没有人知道如何使用CodeDom编译进行字符串插值?
我找到了这个链接:如何使用CSharpCodeProvider定位.net 4.5?
所以我尝试过:
var providerOptions = new Dictionary<string, string>();
providerOptions.Add( "CompilerVersion", "v4.0" );
// Instantiate the compiler.
CodeDomProvider objCodeCompiler = CodeDomProvider.CreateProvider( "CSharp", providerOptions );
Run Code Online (Sandbox Code Playgroud)
但我仍然得到同样的错误.
我还将目标框架更新到.NET Framework 4.6.
注意:我不能指定"v4.5"或"v4.6"或者我会得到:
************** Exception Text **************
System.InvalidOperationException: Compiler executable file csc.exe cannot be found.
at System.CodeDom.Compiler.RedistVersionInfo.GetCompilerPath(IDictionary`2 provOptions, String compilerExecutable)
at Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options, String[] fileNames)
at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromFileBatch(CompilerParameters options, String[] fileNames)
at …Run Code Online (Sandbox Code Playgroud) 我即将将一堆项目从.NET 4.0 + MVC 3迁移到.NET 4.5.2 + MVC5.
为了使这更容易,我创建了一个新的空白MVC项目来比较DLL引用和其他一些东西,如web.config.
在后者中,Visual Studio生成以下条目:
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701"/>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/>
</compilers>
</system.codedom>
Run Code Online (Sandbox Code Playgroud)
但我不知道这究竟是什么.MVC 3项目不包含这些部分.我的理解是它与Roslyn有关吗?
我知道我们可以按照MSDN上所述的members-collection中的顺序强制生成类中的成员.但是,我寻找一些代码,它们还添加了一个序列化属性,提供了这些成员的顺序.所以这就是我希望生成器创建的内容:
class MyClass
{
[XmlElement("TheProperty", Order = 0]
public int MyProperty { get; set; }
[XmlElement("AnotherProperty", Order = 1]
public int AnotherProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
目前,我有一种方法可以循环DOM中所有类型的成员,并将该属性附加到CustomAttributescurrent(public)属性或字段的-member .
var types = code.Types.Cast<CodeTypeDeclaration>().Where(x => !x.IsEnum);
foreach (var members in types.Select(x => x.Members.Cast<CodeTypeMember>()))
{
int i = 0;
var propertiesAndFields = members.Where(x => (
x.Attributes & MemberAttributes.Private) != MemberAttributes.Private
&& (x is CodeMemberField || x is CodeMemberProperty));
foreach (CodeTypeMember member in propertiesAndFields)
{
var attr …Run Code Online (Sandbox Code Playgroud) 我想从C#程序集中执行JavaScript代码,并将JavaScript代码的结果返回给调用的C#代码.
定义我不想做的事情更容易:
我不是试图从我的代码背后调用网页上的JavaScript函数.
我不是要加载WebBrowser控件.
我不想让JavaScript对服务器执行AJAX调用.
我想要做的是在JavaScript中编写单元测试,然后单元测试输出JSON,即使是纯文本也没问题.然后我想要一个通用的C#class/executible,可以加载包含JS的文件,运行JS单元测试,废弃/加载结果,并在后期构建任务中返回带有详细信息的通过/失败.
我认为使用旧的ActiveX ScriptControl是可能的,但似乎应该有一种.NET方法来实现这一点,而不使用SilverLight,DLR或其他尚未发布的东西.有人有主意吗?
namespace Microsoft.JScript.Vsa
{
[Obsolete("There is no replacement for this feature. " +
"Please see the ICodeCompiler documentation for additional help. " +
"http://go.microsoft.com/fwlink/?linkid=14202")]
Run Code Online (Sandbox Code Playgroud)
澄清:我们对使用JSUnit框架用JavaScript编写的JavaScript函数进行了单元测试.在我们的构建过程中,我们必须手动加载网页并单击按钮以确保所有JavaScript单元测试都通过.我希望能够在运行后自动C#单元测试的后期构建过程中执行测试,并报告C#单元测试的成功/失败,并将它们用作指示是否构建被打破.
在我的应用程序中,我使用CodeDom.Compiler从source.cs文件编译另一个程序,我在编译时嵌入了一些资源(exe和dll文件),使用:
// .... rest of code
if (provider.Supports(GeneratorSupport.Resources))
{
cp.EmbeddedResources.Add("MyFile.exe");
}
if (provider.Supports(GeneratorSupport.Resources))
{
cp.EmbeddedResources.Add("New.dll");
}
// ....rest of code
Run Code Online (Sandbox Code Playgroud)
在编译文件中,我需要将嵌入资源作为字节数组读取.现在我通过使用下面的函数和使用将资源提取到磁盘来实现这一点
File.ReadAllBytes("extractedfile.exe");
File.ReadAllBytes("extracteddll.dll");
Run Code Online (Sandbox Code Playgroud)
我使用此函数将两个文件解压缩到磁盘后执行此操作:
public static void ExtractSaveResource(String filename, String location)
{
// Assembly assembly = Assembly.GetExecutingAssembly();
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
// Stream stream = assembly.GetManifestResourceStream("Installer.Properties.mydll.dll"); // or whatever
// string my_namespace = a.GetName().Name.ToString();
Stream resFilestream = a.GetManifestResourceStream(filename);
if (resFilestream != null)
{
BinaryReader br = new BinaryReader(resFilestream);
FileStream fs = new FileStream(location, FileMode.Create); // say
BinaryWriter bw = new …Run Code Online (Sandbox Code Playgroud) msdn文档说添加名称空间导入到CodeNamespace.Imports集合.这将它们放在命名空间内(这是有意义的,因为您将它们添加到命名空间)
namespace Foo
{
using Bar;
//Code
}
Run Code Online (Sandbox Code Playgroud)
但是,我们的代码库的其余部分使用命名空间之外的语句:
using Bar;
namespace Foo
{
//Code
}
Run Code Online (Sandbox Code Playgroud)
是否有一种干净的方式让CodeDom发出第二个版本?
编辑:生成第一个示例的代码如下所示:
CodeNamespace ns = new CodeNamespace("Foo");
ns.Imports.Add(new CodenamespaceImport("Bar"));
CodeCompileUnit cu = new CodeCompileUnit();
cu.Namespaces.Add(ns);
new CSharpCodeProvider().GenerateCodeFromCompileUnit(cu, Console.Out, null);
Run Code Online (Sandbox Code Playgroud) 使用C#代码提供程序和 ICodeCompiler.CompileAssemblyFromSource方法,我试图编译代码文件,以生成可执行程序集.
我想编译的代码使用了可选参数和扩展方法等功能,这些功能仅在使用C#4语言时才可用.
话虽如此,我想编译的代码只需要(并且需要)以.NET Framework 2.0版为目标.
使用前面的代码可以避免任何与语法有关的编译时错误,但是,生成的程序集将以框架的4.0版为目标,这是不合需要的.
var compiler = new CSharpCodeProvider(
new Dictionary<string, string> { { "CompilerVersion", "v4.0" } } );
Run Code Online (Sandbox Code Playgroud)
我怎样才能使代码提供程序针对语言版本4.0但生成一个只需要框架版本2.0的程序集?
codedom ×10
.net ×9
c# ×7
roslyn ×2
asp.net-mvc ×1
c++-cli ×1
csc ×1
javascript ×1
unit-testing ×1
visual-c++ ×1
web-config ×1