当您拥有自动属性时,C#编译器会要求您在任何构造函数上调用this
构造函数,以确保在访问它们之前已初始化所有内容。
如果您不使用自动属性,只是声明值,则可以避免使用this
构造函数。
在结构中对构造函数使用this
的开销是多少?它是否与双重初始化值相同?
如果性能是这种特殊类型的首要问题,您是否建议不使用它?
答案 0 :(得分:4)
我建议不要对结构使用自动属性,因为这意味着它们是可变的 - 如果只是私有的话。
使用只读字段和公共属性在适当的位置提供对它们的访问权限。可变结构几乎总是一个坏主意,并且有各种令人讨厌的小琐事。
首先,您是否确实需要创建自己的值类型?根据我的经验,找到一个很好的理由创建一个结构而不是一个类非常。可能你有一个,但值得检查。
回到原来的问题:如果你关心性能,测量它。总是。在这种情况下,它非常简单 - 您可以使用自动属性编写结构,然后重新实现它。您可以使用#if
块来保留两个选项。然后,您可以测量典型情况,看看差异是否显着。当然,我认为无论如何设计含义可能更重要:)
答案 1 :(得分:2)
是的,这些值将初始化两次,如果没有分析,很难说这个性能是否会显着。
struct
的默认构造函数将所有成员初始化为其默认值。在这种情况发生之后,您的构造函数将在其中运行,您无疑会再次设置这些属性的值。
我认为这与CLR在实例化时初始化引用类型的所有字段的做法没有什么不同。
答案 2 :(得分:1)
当使用自动实现的属性时,C#编译器要求您链接到默认构造函数(即将: this()
附加到构造函数声明)的原因是因为在退出之前需要分配所有变量构造。现在,自动实现的属性会使这一点变得混乱,因为它们不允许您直接访问支持属性的变量。编译器用来解决这个问题的方法是自动将所有变量分配给它们的默认值,为了确保这一点,你必须链接到默认的构造函数。这不是一个特别聪明的方法,但它的工作做得很好。
实际上,这意味着某些变量最终会被初始化两次。但是,我认为这不会是一个很大的性能问题。我很惊讶编译器(或者至少是JIT)并不是简单地删除在构造函数中设置两次的任何变量的第一个初始化语句。一个快速的基准应该为你确认这一点,虽然我很确定你会得到可疑的结果。 (如果你偶然没有,并且你绝对需要微小的性能提升,避免重复的初始化提供,你可以正常方式定义你的属性,即使用支持变量。)
老实说,我的建议甚至不会打扰结构中自动实现的属性。仅使用公共变量来代替它们是完全可以接受的,并且它们提供的功能不比自动实现的属性少。当然,类是不同的情况,但我真的会毫不犹豫地在结构中使用公共变量。 (如果需要,可以正常定义任何复杂属性。)
希望有所帮助。
答案 3 :(得分:1)
不要将自动属性与结构类型一起使用。只需直接暴露字段。如果某个结构具有类型为Foo
的公开字段Bar
,则Foo
是Bar
类型的公开字段(可从Intellisense获取的信息)这一事实告诉我很多事情都要了解它。相比之下,结构Foo
具有公开的读写属性Boz
这一事实并没有说明写入Boz
是否会改变结构中的字段,或者是否将变异Boz
持有引用的某个对象。直接显示字段将提供更清晰的语义,并且通常还会导致代码运行速度更快。