当我输入这段代码时,我正在尝试使用Try Roslyn:
using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.CSharp;
public class C {
public C()
{
x = 4;
}
public int x { get; } = 5;
}
它给了我这个代码:
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;
}
}
我没有得到的是为什么它会在构造函数中两次分配支持字段:
this.<x>k__BackingField = 5;
base(); // This is not valid C#, but it represents the IL correctly.
this.<x>k__BackingField = 4;.
这是网站的错误还是Roslyn编译器实际上是这样做的(会非常愚蠢)?
我的意思是,如果我这样做
public C(int x)
{
this.x = x;
}
public int x { get; } = 5;
创建代码:
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;
}
但它不应该优化出来吗?
答案 0 :(得分:11)
因为你在代码中设置了两次:
update_attributes
修改问题后更新
但它不应该优化出来吗?
它可能,但只有当该类不从另一个在其构造函数中使用该值的类继承时,它才知道它是一个自动属性,而setter不会做任何其他事情。
这将是很多(危险的)假设。在进行这样的优化之前,编译器需要检查很多东西。
答案 1 :(得分:4)
原因是您在代码中设置了两次,包括属性声明和构造函数。
C#6.0只读属性
public int x { get; }
就像关于值赋值的只读字段一样工作:您可以在构造函数中或在声明的位置设置它。
修改
使用多次初始化readonly属性的示例可以是多个构造函数的使用,其中只有一个重新定义了&#34;默认&#34;您为该物业设定的价值。
然而,在您的情况下,优化不是一个坏主意,可能值得将此作为Roslyn github page上的功能请求提出