这是有效的 C# 代码吗?
这是有效的 C# 代码吗?
public class Product
{
[CompilerGenerated]
private string <Name>k__BackingField;
[CompilerGenerated]
private decimal <Price>k__BackingField;
public string Name
{
get;
private set;
}
public decimal Price
{
get;
private set;
}
public Product()
{
}
public static List<Product> GetSampleProducts()
{
List<Product> products = new List<Product>();
Product num1.Price = new decimal(1233, 0, 0, false, 2).Add(num1);
Product product1.Price = new decimal(1332, 0, 0, false, 2).Add(product1);
Product num2.Price = new decimal(2343, 0, 0, false, 2).Add(num2);
Product product2.Price = new decimal(2355, 0, 0, false, 2).Add(product2);
return products;
}
public override string ToString()
{
return string.Format("{0}: {1}", this.Name, this.Price);
}
}
上面的示例取自 JustDecompile(.NET 反编译器),您可以在下面看到原始版本:
using System;
using System.Collections.Generic;
using System.Text;
namespace ProductV3
{
public class Product
{
public string Name { get; private set; }
public decimal Price { get; private set; }
public Product() { }
public static List<Product> GetSampleProducts()
{
return new List<Product>()
{
new Product() { Name = "ProductA", Price = 12.33M },
new Product() { Name = "ProductB", Price = 13.32M },
new Product() { Name = "ProductC", Price = 23.43M },
new Product() { Name = "ProductD", Price = 23.55M }
};
}
public override string ToString()
{
return string.Format("{0}: {1}", Name, Price);
}
}
}
我想知道第一个列表是否是反编译错误,或者它是否是由编译器生成的有效 C# 代码。我非常好奇 GetSampleProducts 方法中的代码是什么。
Is this valid C# code ?
public class Product
{
[CompilerGenerated]
private string <Name>k__BackingField;
[CompilerGenerated]
private decimal <Price>k__BackingField;
public string Name
{
get;
private set;
}
public decimal Price
{
get;
private set;
}
public Product()
{
}
public static List<Product> GetSampleProducts()
{
List<Product> products = new List<Product>();
Product num1.Price = new decimal(1233, 0, 0, false, 2).Add(num1);
Product product1.Price = new decimal(1332, 0, 0, false, 2).Add(product1);
Product num2.Price = new decimal(2343, 0, 0, false, 2).Add(num2);
Product product2.Price = new decimal(2355, 0, 0, false, 2).Add(product2);
return products;
}
public override string ToString()
{
return string.Format("{0}: {1}", this.Name, this.Price);
}
}
The example above is taken from JustDecompile ( a .NET decompiler ) you can see the original version below:
using System;
using System.Collections.Generic;
using System.Text;
namespace ProductV3
{
public class Product
{
public string Name { get; private set; }
public decimal Price { get; private set; }
public Product() { }
public static List<Product> GetSampleProducts()
{
return new List<Product>()
{
new Product() { Name = "ProductA", Price = 12.33M },
new Product() { Name = "ProductB", Price = 13.32M },
new Product() { Name = "ProductC", Price = 23.43M },
new Product() { Name = "ProductD", Price = 23.55M }
};
}
public override string ToString()
{
return string.Format("{0}: {1}", Name, Price);
}
}
}
I want to know if the first listing is a decompiling error or if it is valid C# code, generated by the compiler. I am very curios what is with the code in the method GetSampleProducts.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
通过将其粘贴到编译器中并尝试编译它,可以很容易地看出它不是有效的 C# 代码。
似乎反编译器不知道如何正确处理自动属性和对象文字语法(不确定这是否是正确的术语)
k__BackingField
的一件事实际上是名称IL 中生成的支持场。<
和>
不是 C# 中标识符名称的有效部分,但它们在 IL 中,这就是为什么它们在编译自动属性时收到该名称,因此它不会与您自己创建的任何变量名称冲突。自动属性只是编译器的魔法,毕竟它实际上确实在后台创建了一个私有字段。使用更完整的反编译器,您将获得更好的结果,例如,这就是 DotPeek 反编译时给出的结果(甚至在删除调试符号的情况下进行优化):
It's pretty simple to see that it's not valid C# code by pasting it into a compiler and trying to compile it.
It seems like the decompiler doesn't know how to properly handle auto-properties and the object literal syntax (not sure if that's the proper term)
One thing with
<Price>k__BackingField
that is actually the name of the backing field generated in IL.<
and>
aren't valid parts of an identifier name in C# however they are in IL which is why they receive that name when auto-properties are compiled, so it doesn't conflict with any variable names you might create yourself. Auto-properties are just compiler magic that actually does create a private field in the background after all.With a more complete decompiler you'll get better results, for example, this is what DotPeek gives when decompiling (even optimized with debugging symbols removed):
最好的方法是您获取该代码并尝试自己编译它,看看它是否是有效的 C# 代码。如果最后它确实是有效的 C# 代码,那么您应该阅读该代码并思考它是否确实产生相同的结果。
请记住,一旦代码被编译成 IL,代码本身就会丢失,因此反编译器会尝试编写为您提供与 IL 相同结果的代码...但编译器不可能始终为您提供原始代码的精确副本。
The best way would be for you to take that code and try and compile it yourself to see if it's a valid C# code. If, at the end, it indeed is a valid C# code then you should read the code and think if it actually produces the same result.
Remember that once the code is compiled into IL, the code itself's lost and so the decompiler attempts to write a code that gives you the same result as the IL... but it's impossible for the compiler to always give you an exact copy of the original code.
看起来反编译器对该列表的初始化感到困惑。它肯定没有生成有效的 C# 代码。看起来它试图创建列表中的项目然后添加它们,但它并没有完全正确。反编译某些东西总是很困难,所以我希望时不时地进行调整。
您可以尝试编辑底部部分以显式添加 4 个新项目,并给它们命名。这可能会有帮助。由于反编译器正在处理二进制文件,并且最终由编译器控制它,因此有时对表达算法的方式进行轻微调整可能会影响它。
It looks like that decompiler got confused by the initialization of that list. It definitely did not generate valid C# code. It looks like its trying to make the items of the list and then add them, but it didn't quite get it right. Its always hard to decompile something, so I would expect to have to make tweaks every now and then.
You could try editing the bottom section to explicitly add 4 new items, and give them names. That will probably help. Since the decompiler is working off the binary, and ultimately the compiler controls it, sometimes slight tweaks in how you express your algorithms can effect it.
“backingField”字段和属性只正确了一半:
{ get;私人套装; }
语法被编译为支持字段,以及执行简单赋值和操作的属性。使用权。 IL 会将支持字段列为具有无效名称,这很好。然而,属性应该包括 getter 和 getter 的内容。 setter(是的,由于字段名称无效,这将是一个语法错误,但它是 IL 的准确表示)。这些属性应该包含其编译主体,或者位于{ get;私人套装; }
模式,不存在支持字段。同时具有支持字段和{ get;私人套装; }
语法不正确。GetSampleProducts 的反编译代码当然不正确......它在任何地方都没有使用产品名称。我猜测反编译器不处理对象初始值设定项语法。 (我不知道这是否是正确的名称。)
原文:
反编译:
应该是这样的:
The "backingField" fields & properties are half-correct: The
{ get; private set; }
syntax gets compiled as a backing field, and properties that do a simple assignment & access. The IL will list the backing field as having an invalid name, and that's fine. However, the properties should have included the contents of the getter & setter (which yes, would be a syntax error because of the invalid field name, but it is an accurate representation of the IL). The properties should have either included their compiled bodies, or be in{ get; private set; }
mode with the backing fields not present. Having both the backing field and the{ get; private set; }
syntax is not correct.The decompiled code for GetSampleProducts certainly isn't correct... It doesn't use the product name anywhere. I'm guessing that the decompiler doesn't handle the object initializer syntax. (I don't know if that's the proper name.)
Original:
Decompiled:
Should be something like this: