具有常量值的只读属性,使用自动属性还是非自动属性?

7

在两种属性声明方式之间,是否存在性能/内存使用差异,哪一种更好呢?

public bool Foo => true;

public bool Foo { get; } = true;

此外,如果将布尔值替换为其他不可变值(例如字符串),情况是否会发生改变?

1
第一个示例始终返回“true”。第二个示例仅设置默认值。如果稍后添加了“set”访问器,则可能不再返回“true”。 - Mike Lowery
2个回答

5
我写了这个类作为一个例子。
class Program
{
    public bool A => true;
    public bool B { get; } = true;
}

使用反编译工具,我获得了以下代码:

class Program
{
    // Fields
    [CompilerGenerated, DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly bool <B>k__BackingField = true;

    public bool A
    {
        get
        {
            return true;
        }
    }

    public bool B
    {
        [CompilerGenerated]
        get
        {
            return this.<B>k__BackingField;
        }
    }
}

正如@Fruchtzwerg所提到的,这两种方式返回值的方法相同,但不同之处在于getter方法的实现,因为其中一种返回值为true,而另一种返回具有该值的字段。

谈到性能和内存,第一种方法似乎更好,但如果您只需要此属性为true,我建议使用const


谢谢你和@Fruchtzwerg。只是需要注意,我需要它作为WPF绑定目的的属性。 - Callum Watkins
@CallumWatkins 如果你需要它成为一个属性,我认为第一个更好,因为它没有后备字段。 - Kahbazi
在我看来,Arvin 在这里是正确的,即使以相同的方式访问属性,编译后的 getter 方法也是不同的。Fruchtzwerg 并没有错,但他们只展示了故事的一面。 - Callum Watkins

3
我创建了一个简单的示例来展示差异。我创建了两个类 AB,它们具有不同的属性实现。
public class A
{
    public bool Foo => true;
}

public class B
{
    public bool Foo { get; } = true;
}

使用这些类的简单测试代码足以展示生成的CIL代码的差异:

A a = new A();
B b = new B();

bool c;
c = a.Foo;
c = b.Foo;

反汇编显示以下代码:

            c = a.Foo;
00C50FB0  mov         ecx,dword ptr [ebp-40h]  
00C50FB3  cmp         dword ptr [ecx],ecx  
00C50FB5  call        00C50088  
00C50FBA  mov         dword ptr [ebp-54h],eax  
00C50FBD  movzx       eax,byte ptr [ebp-54h]  
00C50FC1  mov         dword ptr [ebp-48h],eax  
            c = b.Foo;
00C50FC4  mov         ecx,dword ptr [ebp-44h]  
00C50FC7  cmp         dword ptr [ecx],ecx  
00C50FC9  call        00C500A8  
00C50FCE  mov         dword ptr [ebp-58h],eax  
00C50FD1  movzx       eax,byte ptr [ebp-58h]  
00C50FD5  mov         dword ptr [ebp-48h],eax

这意味着没有区别(除了第3行的getter -> 请看@Arvins的答案)。同时,更改类型会在两种实现中产生完全相同的CIL代码。

2
结构是相同的,但区别在于第三行调用的获取器方法的实现。 - Kahbazi
区别在于 => true 是一个每次使用时都会被评估的表达式。在这种情况下,您正在返回一个常量,并且 IL 将被简化为与第二种情况完全相同,即使用只读后备字段并在初始化时间设置其值,获取它只是读取它。 - Paul-Sebastian Manole

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接