Tag: il

使用MSBuild构建后运行测试时出现MissingManifestResourceException(.mresource在清单中有路径)

我在命令行上使用MSBuild的构建服务器上的C#项目的嵌入资源有问题。 在Visual Studio中构建和运行测试时,该项目工作得很好,但是当从命令行运行MSBuild时,运行测试时会出现以下问题: System.Resources.MissingManifestResourceException:找不到适合指定文化或中性文化的任何资源。 确保“.Properties.Resources.resources”在编译时正确嵌入或链接到程序集“”,或者所有所需的附属程序集都是可加载和完全签名的。 System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture,Boolean)中的System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo文化,Dictionary`2 localResourceSets,Boolean tryParents,Boolean createIfNotExists,StackCrawlMark和stackMark)中的System.Resources.ManifestBasedResourceGroveler.HandleResourceStreamMissing(String fileName)位于System.Resources.get_SomeResource()的System.Resources.ResourceManager.GetString(String name,CultureInfo culture)的System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture,Boolean createIfNotExists,Boolean tryParents)中的createIfNotExists,Boolean tryParents,StackCrawlMark和stackMark in \ Properties \ Resources.Designer.cs:第87行 我已将问题跟踪到生成的IL(我使用ildasm)。 在Visual Studio中进行bulding时,在程序集的清单中设置以下内容: .mresource public .Properties.Resources.resources { // Offset: 0x00000000 Length: 0x00000236 } 但是在使用MSBuild构建时会生成以下输出: .mresource public ‘../..//Build/_AnyCPU_Debug_Obj/.Properties.Resources.resources’ { // Offset: 0x00000000 Length: 0x00000236 } 因为可以看到资源的路径突然成为资源名称的一部分。 有没有人有任何想法如何解决这个问题?

是否存在用于防止NullReferenceException的常见模式中的竞争条件?

我问了这个问题并得到了这个有趣(并且有点令人不安)的答案。 Daniel在他的回答中指出(除非我读错了) ECMA-335 CLI规范允许编译器生成从以下DoCallback方法抛出NullReferenceException代码。 class MyClass { private Action _Callback; public Action Callback { get { return _Callback; } set { _Callback = value; } } public void DoCallback() { Action local; local = Callback; if (local == null) local = new Action(() => { }); local(); } } 他说,为了保证不抛出NullReferenceException ,应该在_Callback上使用volatile关键字,或者在local = Callback;行周围使用lock local = […]

编译器为delegate关键字生成的密封类包含虚拟方法

在C#中使用delegate关键字时,C#编译器会自动生成从System.MulticastDelegate类派生的类。 此编译器生成的类还包含3个方法: Invoke, BeginInvoke and EndInvoke 。 所有这三种方法都标记为public virtual extern但有趣的是,类本身标记为sealed 。 在密封类中定义的虚拟方法不仅违反直觉,而且在C#中实际上是非法的。 所以我的问题是,是否有一个特定的原因,或者它只是其中一个无害的事情,记住一些假设的未来增强? 编辑1: 可能的原因是强制使用’callVirt’IL操作码而不是’调用’,以便在尝试执行这三种方法中的任何一种之前,CLR始终检查委托对象为空? 虽然我不明白为什么delegate在这方面应该是一个特例。 也不是强制使用callvirt的性能打击(虽然它可能是微不足道的) 编辑2: 添加了CIL标记,因为事实certificate定义委托的C#方式实际上是由CIL标准强制执行的。 标准规定(以下不是全文) 代理应具有System.Delegate的基本类型。 代表应宣布密封 ,代表的唯一成员应为此处规定的前两种或全部四种方法。 这些方法应声明为运行时和管理。 它们不应具有身体,因为该身体应由VES自动创建。 委托上可用的其他方法inheritance自基类库中的System.Delegate类。 委托方法是: 实例构造函数 Invoke方法应该是虚拟的 BeginInvoke方法(如果存在)应为虚拟方法 EndInvoke方法应该是虚拟的 所以这绝对不是编译器进程的副作用,或者类似于其他有趣的编译器输出。 如果标准强调某些东西,那必须是出于某种充分的理由和理由。 所以现在的问题是为什么代表们的CIL标准同时强调密封和虚拟? 渔获物在这里吗?: 它们不应具有身体,因为该身体应由VES自动创建。 它们是否标记为虚拟,以便在调用这些方法时可以执行VES / CLR生成的主体?

CLR在调用struct的方法时如何工作

我想我已经知道了一堂课的答案,只想确认我的理解是正确的。 假设我有一个ClassA ,它的实例名为a 。 当调用a.MethodA() : (1)CLR通过堆中a的类型指针找到ClassA的类型 (类型已经加载到堆中) (2)在类型中找到MethodA ,如果找不到,则转到其基类型,直到object类。 也许我的理解不太准确,但我认为这是基本正确的(纠正我,如果它是错的!)。 这是一个简单结构的问题。 struct MyStruct { public void MethodA() { } } 我有var x = new MyStruct(); ,它的值在堆栈上, MyStruct的类型已加载到堆中。 当执行x.MethodA() ,当然没有拳击。 CLR如何找到MethodA并获取IL并执行/ JIT呢? 我认为答案可能是:(如果我错了,再次纠正我) (1)我们在堆栈上有x的声明类型 。 CLR通过堆栈上的信息找到它的类型,并在其类型中找到MethodA 。 – 让我们称之为assumptionA 如果你告诉我我的assumptionA是正确的,我会很高兴的。 但即使它是错的,它也说明了一个道理:CLR有一种方法可以在没有装箱的情况下找到结构类型。 那么x.ToString()或x.GetType()呢? 我们知道该值将被加框,然后它将像一个类一样执行。 但为什么我们需要拳击呢? 既然我们可以得到它的类型(假设A告诉我们),为什么不去它的基类型并找到方法(就像一个类)? 为什么需要昂贵的箱子操作呢?

为什么我不能修改取消装箱转换的结果?

struct Point { public int x; public int y; } void Main() { Point p; px = 1; py = 1; Object o = p; ((Point) o).x = 4; // error ((Point) o).x = 5; // error ((Point) o).x = 6; // error p = (Point) o // expect 6 } 为什么不编译 ldloc.1 // o […]

为什么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 ? […]