Tag: compiler construction

儿童范围&CS0136

以下代码无法编译声明“在此范围内无法声明名为’st’的局部变量,因为它会给’st’赋予不同的含义,’st’已在’子’范围内用于表示其他内容”: var l = new List(); l.Find(st => st.EndsWith(“12”)); string st = “why this fails?”; 我理解为什么这不起作用: string preParent = “”; { string preParent = “Should fail cause we change the meaning”; } 当我们执行以下操作时,我们得到“CS0103:当前上下文中不存在名称’postParent’”: { string postParent=string.Empty; } postParent = “Should this work?”; 我没有得到的是为什么编译器足够聪明才能看到postParent不在范围内,但是不允许我定义一个与子范围内使用的变量同名的新变量(显然是此时的范围)。 编译器是否通过拒绝让我使用变量来简单地强制执行范围? 如果是这样有意义。 =========== 编辑: 我想我也觉得有趣的是你如何在一个方法中的两个子范围内拥有相同的变量,所以这是有效的: { string thisWorks= string.Empty; } { string […]

以编程方式将资源嵌入.NET程序集中

我有一个嵌入了特定资源文件的编译.NET程序集(名为’Script.xml’)。 我需要以编程方式将其更改为另一个。 如果不从源代码重新编译,这可能吗? 目前,我搜索文件中我知道的文本并且效果很好。 但我需要为另一个项目做这件事,我不知道资源文件的任何内容,我需要找到另一种方法。 FileStream exe = new FileStream(currentexe, FileMode.Open); //find xml part of exefile string find = “”; string lastchars = new string(‘ ‘, find.Length); while (exe.CanRead) { lastchars = lastchars.Substring(1) + (char)exe.ReadByte(); if (lastchars == find) { exe.Seek(-find.Length, SeekOrigin.Current); break; } } //output serialized script int bytenum = 0; foreach (byte c […]

在循环中执行array.length或list.count是否代价高昂

我知道在JavaScript中,创建一个这样的for循环: for(int i = 0; i < arr.length; i++)是昂贵的,因为它每次都计算数组长度。 对于列表和数组,这种行为在c#中是否代价高昂。 或者在编译时它是否经过优化? 还有其他语言如Java,这是如何处理的?

在什么级别C#编译器或JIT优化应用程序代码?

我想知道这些信息以减少我的代码大小,所以我不会浪费时间来优化将由编译器或JIT完成的事情。 例如: 如果我们假设编译器内联调用属性的get函数,那么我不必将返回值保存在局部变量中以避免函数调用。 我想推荐一个描述正在发生的事情的好参考?

如何通过JIT编译器编译generics?

我知道generics是由JIT编译的(就像其他所有东西一样),与编译代码时生成的模板形成对比。 问题是可以使用reflection在运行时创建新的generics类型。 这当然会影响通用的约束。 哪个已经通过了语义解析器。 有人能解释一下这是如何处理的吗? 究竟发生了什么? (代码生成和语义检查)

生成自定义编译时警告C#

我正在使用VS2008,并希望根据属性上的自定义属性创建编译时警告/错误(如果可能)。 目前有两个案例让我感兴趣: [MyAttribute (typeof(MyClass)] MyClass必须实现一个接口。 目前我在属性的构造函数中声明了这一点,但是由于堆栈跟踪的性质,这不容易跟踪: public MyAttribute (Type MyClassType) { System.Diagnostics.Debug.Assert(typeof(MyInterface).IsAssignableFrom(MyClassType), “Editor must implement interface: ” + typeof(MyInterface).Name); } 我感兴趣的第二种情况是我在属性中定义了一个类型,如果该类型实现了一个接口,那么如果另一个属性不存在则应该显示警告。 IE if(MyClass.Implements(SomeInterface)&&!Exists(SomeAttibute)){Generate Warning} [MyAttribute(typeof(MyClass)] // Comment next line to generate warning [Foo (“Bar”)] 谢谢!

C# – 值类型等于方法 – 为什么编译器使用reflection?

我只是遇到了一些非常奇怪的东西:当你在值类型上使用Equals()方法时(如果这个方法当然没有被覆盖)你会得到一些非常慢的东西 – 使用一对一的字段进行比较反思! 如: public struct MyStruct{ int i; } (…) MyStruct s, t; si = 0; ti = 1; if ( s.Equals( t )) /* si will be compared to ti via reflection here. */ (…) 我的问题:为什么C#编译器不生成比较值类型的简单方法? 像(在MyStruct的定义中): public override bool Equals( Object o ){ if ( this.i == oi ) return true; else […]

C#编译器应该发出警告但不是吗?

我的团队中有人尝试在空catch子句中修复“未使用变量”警告。 try { … } catch (Exception ex) { } – >发出关于ex未被使用的警告。 到现在为止还挺好。 修复是这样的: try { … } catch (Exception ex) { string s = ex.Message; } 看到这个,我想“很棒,所以现在编译器会抱怨没有被使用。” 但事实并非如此! 这段代码没有警告,我无法弄清楚原因。 有任何想法吗? PS。 我知道将exception静音的全能条款是一件坏事,但这是一个不同的话题。 我也知道通过做这样的事情可以更好地消除初始警告,这也不是重点。 try { … } catch (Exception) { } 要么 try { … } catch { }

语句块中的变量范围

for (int i = 0; i < 10; i++) { Foo(); } int i = 10; // error, 'i' already exists —————————————- for (int i = 0; i < 10; i++) { Foo(); } i = 10; // error, 'i' doesn't exist 根据我对范围的理解,第一个例子应该没​​问题。 它们都不允许的事实似乎更奇怪。 当然’我’要么在范围内,要么不在范围内。 有什么不明显的范围我不明白这意味着编译器真的无法解决这个问题? 或者只是一个保姆状态编译案例?

为什么C#编译器为GetType()方法调用发出callvirt指令?

我很想知道为什么会这样。 请阅读下面的代码示例以及每个部分下面的注释中发出的相应IL: using System; class Program { static void Main() { Object o = new Object(); o.GetType(); // L_0001: newobj instance void [mscorlib]System.Object::.ctor() // L_0006: stloc.0 // L_0007: ldloc.0 // L_0008: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType() new Object().GetType(); // L_000e: newobj instance void [mscorlib]System.Object::.ctor() // L_0013: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType() } } 为什么编译器为第一部分发出callvirt而第二部分call ? […]