I was trying around a bit with Try Roslyn when I entered this piece of code:
using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.CSharp;
public class C {
public C()
{
x = 4;
}
public int x { get; } = 5;
}
And it gave me back this code:
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[module: UnverifiableCode]
public class C
{
[DebuggerBrowsable(DebuggerBrowsableState.Never), CompilerGenerated]
private readonly int <x>k__BackingField;
public int x
{
[CompilerGenerated]
get
{
return this.<x>k__BackingField;
}
}
public C()
{
this.<x>k__BackingField = 5;
base(); // This is not valid C#, but it represents the IL correctly.
this.<x>k__BackingField = 4;
}
}
What I don't get is why it would do the assignment of the backing field twice inside of the constructor:
this.<x>k__BackingField = 5;
base(); // This is not valid C#, but it represents the IL correctly.
this.<x>k__BackingField = 4;.
Is this an error of the website or does the Roslyn compiler actually do this (would be really dumb imo)?
What I mean is that if I do
public C(int x)
{
this.x = x;
}
public int x { get; } = 5;
And have that code created:
public C(int x)
{
this.<x>k__BackingField = 5;
base(); // This is not valid C#, but it represents the IL correctly.
this.<x>k__BackingField = x;
}
But shouldn't it optimize that out?
Because JavaScript uses the IEEE 754 standard for Math, it makes use of 64-bit floating numbers. This causes precision errors when doing floating point (decimal) calculations, in short, due to computers working in Base 2 while decimal is Base 10.
A floating point number, is a positive or negative whole number with a decimal point. For example, 5.5, 0.25, and -103.342 are all floating point numbers, while 91, and 0 are not. Floating point numbers get their name from the way the decimal point can "float" to any position necessary.
The floating-point data type is a family of data types that act alike and differ only in the size of their domains (the allowable values). The floating-point family of data types represents number values with fractional parts. They are technically stored as two integer values: a mantissa and an exponent.
A generic holder for the value of a property. A Value object can be used without knowing the actual property type ( STRING , DOUBLE , BINARY etc.). Any implementation of this interface must adhere to the following behavior: A Value object can be read using type-specific get methods.
Because you set it twice in your code:
public C()
{
//here
x = 4;
}
//and here
public int x { get; } = 5;
Update after edit of question
But shouldn't it optimize that out?
It probably could, but only if that class doesn't inherit from another class that uses that value in its constructor, it knows that it's an auto-property and the setter doesn't do anything else.
That would be a lot of (dangerous) assumptions. The compiler needs to check a lot of things before making an optimization like that.
The reason is that you are setting it twice in your code, both in the property declaration and in the constructor.
The C# 6.0 readonly property
public int x { get; }
Works just like a readonly field regarding value assignment: you can set it in either the constructor or at the place of the declaration.
EDIT
An example for the usage of initializing the readonly property for multiple time can be the usage of multiple constructors, where only one redefines the "default" value you set for the property.
However in your case, optimization would not be a bad idea, it might be worthwhile to raise this as a feature request on the Roslyn github page
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With