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.
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):
public class Product
{
public string Name { get; private set; }
public Decimal Price { get; private set; }
public static List<Product> GetSampleProducts()
{
return new List<Product>()
{
new Product()
{
Name = "ProductA",
Price = new Decimal(1233, 0, 0, false, (byte) 2)
},
new Product()
{
Name = "ProductB",
Price = new Decimal(1332, 0, 0, false, (byte) 2)
},
new Product()
{
Name = "ProductC",
Price = new Decimal(2343, 0, 0, false, (byte) 2)
},
new Product()
{
Name = "ProductD",
Price = new Decimal(2355, 0, 0, false, (byte) 2)
}
};
}
public override string ToString()
{
return string.Format("{0}: {1}", (object) this.Name, (object) this.Price);
}
}