使用自动属性实现单例是一个好主意吗?
我最近发现了汽车属性并且非常喜欢它们。目前我正尝试在任何可以的地方使用它们。不仅仅是为了能够在任何地方使用它们,更多的是为了看看它们在大多数情况下的工作效果如何。
现在我正在创建一个单例并想:“嘿,让我们在这里也尝试一下自动属性”。
public class MySingleton
{
public static MySingleton MySingleton { get; private set; }
private MySingleton() {}
static MySingleton() { MySingleton = new MySingleton(); }
}
所以我的问题是:“像这样实现单例是个好主意吗?”
我并不是在问单身人士总体上是否是一个好主意。
I recently found out about auto-properties and like them quite a lot. At this moment I am trying to use them everywhere where I can. Not really to just be able to use them everywhere, but more to see how well they work in most situations.
Now I am making a singleton and thought:"Hey, let's try auto-properties here as well".
public class MySingleton
{
public static MySingleton MySingleton { get; private set; }
private MySingleton() {}
static MySingleton() { MySingleton = new MySingleton(); }
}
So my question is: "Is it a good idea to implement a singleton like this?"
I am not asking whether a singleton in general is a good idea.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我个人不会这样做。我不喜欢使用带有私有 setter 的自动实现的属性,当您真正想要由只读变量支持的只读属性时,您永远不会调用该属性。只需再一行代码就可以更明确地表达您的意思:
这样就没有人会试图更改单例类来重新分配属性或变量,因为编译器会阻止它们。他们必须添加一个设置器和/或使变量变为非只读,这是一个更大的更改 - 希望他们会重新考虑这一更改。
换句话说:
从 C# 6 开始,使用自动实现的只读属性会更容易:
I wouldn't personally do that. I don't like using automatically implemented properties with a private setter that you never call where really you want a read-only property backed by a read-only variable. It's only one more line of code to be more explicit about what you mean:
This way no-one's even tempted to change the singleton class to reassign either the property or the variable, because the compiler will stop them. They'd have to add a setter and/or make the variable non-readonly, which is a bigger change - one which hopefully they'd reconsider.
In other words:
As of C# 6, this is easier with read-only automatically implemented properties though:
我会从与乔恩稍微不同的方向来处理这个问题。 无论对象是否是单例,从逻辑上讲,它首先是否最好被建模为属性?
属性应该代表...属性。 (明显队长再次出击!)你知道。颜色。长度。高度。姓名。家长。所有你从逻辑上认为是事物属性的东西。
我无法想象一个对象的属性在逻辑上是单例。也许你已经想出了一个我没有想到的场景;今天早上我还没有吃胡椒博士的减肥药。但我怀疑这是对模型语义的滥用。
你能描述一下什么是单身人士,以及为什么你相信它是某物的属性吗?
话虽如此,我自己也经常使用这种模式;通常是这样的:
“空”在逻辑上是不可变堆栈的属性吗?不。在这里,能够说的令人信服的好处
胜过了我对属性逻辑上成为属性的渴望。光说起来
就觉得奇怪。
在这种情况下,是拥有一个只读字段和一个常规属性更好,还是一个静态构造函数和一个 autoprop 更好,似乎不是一个有趣的问题,而是首先是否将其设为一个属性。出于“纯粹”的心情,我可能会站在乔恩一边,并将其设为只读字段。但出于懒惰,我也经常使用带有私有 setter 的 autoprop 模式来创建逻辑上不可变的对象。
全面考虑问题怎么样?
I would approach this from a slightly different direction than Jon. Regardless of whether the object is a singleton, is it logically best modeled as a property in the first place?
Properties are supposed to represent... properties. (Captain Obvious strikes again!) You know. Color. Length. Height. Name. Parent. All stuff that you would logically consider to be a property of a thing.
I cannot conceive of a property of an object which is logically a singleton. Maybe you've come up with a scenario that I haven't thought of; I haven't had any Diet Dr. Pepper yet this morning. But I am suspicious that this is an abuse of the model semantics.
Can you describe what the singleton is, and why you believe it to be a property of something?
All that said, I myself use this pattern frequently; usually like this:
Is "Empty" logically a property of an immutable stack? No. Here the compelling benefit of being able to say
trumps my desire for properties to logically be properties. Saying
just seems weird.
Whether it is better in this case to have a readonly field and a regular property, or a static ctor and an autoprop, seems like less of an interesting question than whether to make it a property in the first place. In a "purist" mood I would likely side with Jon and make it a readonly field. But I also frequently use the pattern of making autoprops with private setters for logically immutable objects, just out of laziness.
How's that for taking all sides of a question?
我看不出有什么理由说这是不正确的。毕竟,自动属性只是私有(编译器生成的)支持字段的访问器的语法糖。
I don't see any reason why this wouldn't be correct. After all, auto-properties are just syntactic sugar for accessors for a private (compiler-generated) backing field.
当然,我不认为这有什么问题。
Sure, I don't see any problem with that.
汽车财产?不,我不会,但会在单例上使用 setter,是的,我会这样做。我认为你想要对它拥有比汽车财产更多的控制权。
...这里非常欢迎建设性的反馈。在这家受人尊敬的公司中,这感觉像是一个勇敢(或愚蠢)的举动......
我的场景是,一个 WPF 应用程序有一个可以加载和保存的当前项目。当前的项目设置在整个应用程序中使用...
INotifyPropertyChanged
界面。NotifyStaticPropertyChanged< /代码>。
INotifyPropertyChanged
与单例属性上的 WPF 绑定配合得很好。Settings
的实例使用 JSON.NET 进行[反]序列化,因此单例上有[JsonIgnore]
属性。我在将其加载到单例或将其保存到磁盘之前对其进行验证。public
getter 的public
,因为 WPF 绑定仅适用于公共属性。internal
setter 不会影响它。Settings
的所有属性对于 WPF 绑定都是公共的。我在代码中保留了所有“噪音”,因为有些人可能会发现它很有用。
用于将单例设置为新加载的项目,
settings
只是setter 可能不是线程安全的,但我只将其设置在 UI 线程的一个位置,所以我并不害怕。您可以按照 http://csharpindepth.com/Articles/General 的受人尊敬的建议使其线程安全/Singleton.aspx
我意识到 OP 没有询问 WPF,但我认为它与展示为什么您可能想要设置单例相关。我这样做是因为这是最简单的解决方案。
Auto property? No, I wouldn't but using a setter on a singleton, yes I did. I think you want more control over it than an auto property will give you.
... constructive feedback is more than welcome here, please. This feels like a brave (or foolish) move in this esteemed company ...
My scenario, a WPF app that has a Current Project than can be loaded and saved. The current project settings are used all over the application...
INotifyPropertyChanged
interface.NotifyStaticPropertyChanged
.INotifyPropertyChanged
works fine with WPF bindings on the singleton's properties.Settings
is [de]serialized using JSON.NET, hence the[JsonIgnore]
attribute on the singleton. I validate it before loading it into the singleton or saving it to disk.public
with apublic
getter because WPF bindings only work on public properties. Theinternal
setter doesn't affect it. All the properties ofSettings
are public for WPF binding.I left all the "noise" in the code because some may find it useful.
usage to set the singleton to a newly loaded project,
settings
is simplyThe setter probably isn't thread-safe but I only set it in one place from the UI thread so I'm not scared. You could make it thread safe following the esteemed advice at http://csharpindepth.com/Articles/General/Singleton.aspx
I realise the OP didn't ask about WPF but I think it's relevant to show why you may want to set a singleton. I did it because it is the simplest solution.
使用 lambda 样式(>= C# 6)总结+替代语法,又名计算属性(又名表达式主体成员):
该代码在功能上完全等同于 Jon Skeet 的答案,这里再次使用“实例”。我并不指望这会得到赞扬,但我认为这个更新的总结在一个地方进行了解释是值得的,因为这个 C#6 问题和答案扩展了旧的封闭线程,其中已经讨论了 Singleton 的变体。
您可能会认为带有显式缺失集的自动属性样式更清楚地表达了只读属性的意图,但最终它是基于样式的,并且这两种样式在现代 C# 中都很常见。
以下是所有细节和历史参考:
关于懒惰的讨论:http://csharpindepth.com /Articles/General/Beforefieldinit.aspx
简单总结:只要类中没有引入其他静态字段/属性,上述实现就会表现出惰性。
(但这是一个可能依赖于 .NET 实现的领域。)
有关单例和线程安全的不同实现的讨论(较旧的 C# 样式):
帖子
原始 关闭):
C# 的单例模式
Wrap up + alternative syntax with lambda style (>= C# 6) aka computed property (aka expression-bodied member):
The code is functionally fully equivalent to the answer of Jon Skeet, here again with "Instance". I don´t expect kudos for this, but I think this updated wrapup with explanation at one place is it worth, because this C#6 question and answers extend the old closed thread where variations of Singleton have been discussed.
You could argue the automatic-property-style with an explicitly missing set expresses clearer the intent of a read-only property, but in the end it is style based, and both styles are common in modern C#.
Here is all detail and historical reference at one place:
Discussion about lazyness: http://csharpindepth.com/Articles/General/Beforefieldinit.aspx
Simplified summary: The above implementation behaves lazy as long as no other static fields/properties are introduced in the class.
(But this is an area which can be .NET implementation-dependent.)
Discussion concerning different implementations of Singleton and thread safety (older C# styles):
http://csharpindepth.com/Articles/General/Singleton.aspx
Original thread (closed):
Singleton Pattern for C#