Tag: compiler construction

使用ANTLR构建自己的C#编译器:编译单元

//创建一个扫描程序,从传递给我们的输入流中读取CSLexer lexer = new CSLexer(new ANTLRFileStream(f)); tokens.TokenSource = lexer; // Create a parser that reads from the scanner CSParser parser = new CSParser(tokens); // start parsing at the compilationUnit rule CSParser.compilation_unit_return x = parser.compilation_unit(); object ast = x.Tree; 我怎么能用compilation_unit_return类型的x来提取它的根,它的类,它的方法等? 我必须提取其适配器吗? 我怎么做? 请注意,compilation_unit_return在我的CSParser中定义(由ANTLR自动生成): public class compilation_unit_return : ParserRuleReturnScope { private object tree; override public object Tree […]

显式接口实现不能是虚拟的

为了记录,我已经看过这个连接项,但我真的不明白支持这个问题会是什么。 说我有以下代码: public interface IInterface { void Method(); } public class Base : IInterface { virtual void IInterface.Method() { throw new NotImplementedException(); } } 虚拟标识符有什么问题? 拥有虚拟修饰符可以override指示基类中有不同的实现。 我现在可以通过删除虚方法并创建如下的派生类来使其工作: public class Derived : IInterface { void IInterface.Method() { throw new NotImplementedException(); } } 但是这样我真的没有迹象表明我压倒了什么。 更新: 根据C#(部分:20.4.1显式接口成员实现)规范,有两个原因。 隐藏某些方法(我正在使用它)。 具有相同签名但具有不同返回类型的2个函数(例如,对IClonable有用)。 它没有说明为什么你不能使这些方法虚拟。 UPDATE2: 鉴于答案,我认为我应该在这里重新提出真正的问题。 如果以上两个原因是首先使接口的显式实现成为可能的原因。 如果将方法设为虚拟,为什么会出现问题?

C#编译器错误? 用于Expression中的只写属性的对象初始化程序语法使csc崩溃

您可能会认为这是一个错误报告,但是我很好奇我是否在这里非常错误,或者是否有来自Eric或Microsoft的其他人的解释。 更新 现在,这是作为 Microsoft Connect上的错误发布的 。 描述 考虑以下课程: class A { public object B { set { } } } 这里, AB是一个只写但其他方面很好的属性。 现在,想象一下我们在表达式中分配它 : Expression<Func> expr = () => new A { B = new object { } }; 此代码使C#编译器( 3.5 .30729.4926和4.0 .30319.1)吐出 内部编译器错误(地址013E213F处的0xc0000005):可能的罪魁祸首是“BIND”。 和崩溃。 但是, 仅使用构造函数( ( ) )替换对象初始化程序语法( { } )就可以了 。 完整的复制代码: […]

具有可空值类型参数的扩展方法解析

public static class Extension { public static void Test(this DateTime? dt) { } } void Main() { var now = DateTime.Now; Extension.Test(now); // ok now.Test(); // compile time error } 我只是好奇,为什么编译器在作为扩展名调用时无法解析相同的方法?

在运行时编译C#数组并在代码中使用它?

我知道C#代码可以在运行时使用C#编译 。 但是,因为我几分钟前刚读过这篇文章,所以我非常不满意。 我通过例子学到了很多东西。 所以告诉我。 如果我想编译类似的东西: // MapScript.CS String[] LevelMap = { “WWWWWWWWWWWWWWWWWWW”, “WGGGGGGGGGGGGGGGGGW”, “WGGGGGGGGGGGGGGGGGW”, “WWWWWWWWWWWWWWWWWWW” }; 并在我的代码中使用此数组,我该怎么做呢? 在伪代码中我想做这样的事情: Open(“MapScript.CS”); String[] levelMap = CompileArray(“levelMap”); // use the array

.NET 3.5的哪些function可以在.NET 2.0应用程序中使用?

我有一个我在Visual Studio 2008中开发的应用程序,但项目设置为.NET 2.0。 该应用程序将在仅安装了.NET 2.0的盒子上运行。 我知道我可以使用.NET 3.5 c#编译器的一些function,并将我的代码编译为.NET 2.0运行时理解的MSIL。 我可以在.NET 2.0应用程序中使用.NET 3.5的哪些function? 编辑:我想到的是扩展方法,Linq,lambdas,对象初始化器,集合初始化器和其他编译器糖果。

使用带有.net 4.5 beta的CSharpCodeProvider

我最近安装了Visual Studio 11 Beta,我正在尝试更新现有的4.0项目以使用4.5。 在程序中,它使用CSharpCodeProvider编译一些动态生成的代码。 /// /// Compile and return a reference to the compiled assembly /// private Assembly Compile() { var referencedDlls = new List { “mscorlib.dll”, “System.dll”, “System.Core.dll”, }; referencedDlls.AddRange(RequiredReferences); var parameters = new CompilerParameters( assemblyNames: referencedDlls.ToArray(), outputName: GeneratedDllFileName, // only include debug information if we are currently debugging includeDebugInformation: Debugger.IsAttached); parameters.TreatWarningsAsErrors = […]

强制.NET JIT编译器在应用程序启动期间生成最优化的代码

我正在用C#编写一个DSP应用程序(基本上是一个多轨编辑器)。 我在不同的机器上进行了很长一段时间的分析,我注意到了一些“好奇”的东西。 在我的家用机器上,回放循环的第一次运行占用了可用时间的大约50%-60%,(我认为这是由于JIT正在完成其工作),然后对于后续循环,它会下降到稳定的5 % 消费。 问题是,如果我在较慢的计算机上运行应用程序,第一次运行占用的时间超过可用时间,导致播放中断并弄乱输出音频,这是不可接受的。 之后,它降至8%-10%的消费量。 即使在第一次运行之后,应用程序仍然不时地调用一些耗时的例程(每2秒或多或少),这导致稳定的5%消耗经历非常短的20%-25%的峰值。 我注意到如果我让应用程序运行一段时间,这些峰值也会下降到7%-10%。 (我不确定这是否是由于JIT重新编译这些代码部分)。 所以,我对JIT有一个严重的问题。 虽然应用程序即使在非常慢的机器中也能很好地运行,但这些“编译风暴”将成为一个大问题。 我试图弄清楚如何解决这个问题,我想出了一个想法,即用一个属性标记所有’明智的’例程,告诉应用程序在启动时预先“挤压”它们因此,当他们真正需要时,他们将完全优化。 但这只是一个想法(我也不太喜欢),我想知道是否有更好的解决方案来解决整个问题。 我想听听你们的想法。 (NGEN应用程序不是一个选项,我喜欢并希望我能获得所有JIT优化。) 编辑: 内存消耗和垃圾收集没有问题,我正在使用对象池,播放期间的最大内存峰值为304 Kb。

如何从.NET中的用户类distingush编译器生成的类

我的程序中有一段代码通过检查它们的类型名称中是否包含“DisplayClass”来区分编译器生成的类。 在阅读这个答案后 ,我想我需要一个更好的方法。 如何从.NET中的用户类中删除编译器生成的类?

当两个重载具有相同的签名时,调用构造函数重载

考虑以下课程, class Foo { public Foo(int count) { /* .. */ } public Foo(int count) { /* .. */ } } 上面的代码无效,不会编译。 现在考虑以下代码, class Foo { public Foo(int count) { /* .. */ } public Foo(T t) { /* .. */ } } static void Main(string[] args) { Foo foo = new Foo(1); } 以上代码有效且编译良好。 […]