Csharp/C#教程:使用自动属性实现单例是一个好主意吗?分享


使用自动属性实现单例是一个好主意吗?

我最近发现了有关自动属性的内容并且非常喜欢它们。 此刻,我正试图在任何地方使用它们。 不仅仅是能够在任何地方使用它们,而是更多地了解它们在大多数情况下的工作情况。

现在我正在制作一个单身人士并且想:“嘿,让我们在这里尝试自动属性”。

public class MySingleton { public static MySingleton MySingleton { get; private set; } private MySingleton() {} static MySingleton() { MySingleton = new MySingleton(); } } 

所以我的问题是:“实现像这样的单身人士是一个好主意吗?”

我不是在问一个单身一般是不是一个好主意。

我不会亲自这样做。 我不喜欢使用自动实现的属性与私有的setter,你永远不会调用你想要一个只读变量支持的只读属性。 关于你的意思,只有一行代码更明确:

 public sealed class MySingleton { private static readonly MySingleton mySingleton; public static MySingleton MySingleton { get { return mySingleton; } } private MySingleton() {} static MySingleton() { mySingleton = new MySingleton(); } } 

这样,没有人甚至试图改变单例类来重新分配属性或变量,因为编译器会阻止它们。 他们必须添加一个setter和/或使变量非读取,这是一个更大的变化 – 希望他们重新考虑。

换一种说法:

从C#6开始,使用只读自动实现的属性会更容易:

 public sealed class MySingleton { public static MySingleton MySingleton { get; } = new MySingleton(); private MySingleton() {} static MySingleton() {} } 

我会从与Jon略有不同的方向来解决这个问题。 无论对象是否是单例, 它首先在逻辑上最好地建模为属性吗?

属性应该代表…属性。 (Obvious队长再次罢工!)你知道。 颜色。 长度。 高度。 名称。 家长。 你在逻辑上认为是物的属性的所有东西。

我无法想象一个逻辑上是单身的物体的属性 。 也许你想出了一个我没有想过的场景; 今天早上我没有任何Diet Pepper博士。 但我怀疑这是滥用模型语义。

你能描述单身人士是什么,为什么你认为它是某种东西的财产?

总而言之,我自己经常使用这种模式; 通常是这样的:

 class ImmutableStack { private static readonly ImmutableStack emptystack = whatever; public static ImmutableStack Empty { get { return emptystack; } } ... 

逻辑上“空”是不可变堆栈的属性吗? 不,这是能够说出来的令人信服的好处

 var stack = ImmutableStack.Empty; 

胜过我对物业逻辑上属性的渴望。 话

 var stack = ImmutableStack.GetEmpty(); 

看起来很奇怪。

在这种情况下,是否更好地拥有只读字段和常规属性,或静态ctor和autoprop,似乎不是一个有趣的问题,而不是首先使它成为属性。 在一种“纯粹主义”的情绪中,我很可能会与Jon站在一起并使其成为一个只读的领域。 但是我也经常使用私有设置器的autoprops模式用于逻辑上不可变的对象,只是出于懒惰。

如何解决问题的各个方面?

我认为没有任何理由说这不正确。 毕竟,自动属性只是私有(编译器生成的)支持字段的访问器的语法糖。

当然,我没有看到任何问题。

汽车财产? 不,我不会在单身人士身上使用二传手,是的,我做到了。 我想你想要比汽车财产给你更多的控制权。

…请提供建设性的反馈。 在这家受人尊敬的公司中,这感觉就像一个勇敢(或愚蠢)的举动……

我的场景,一个WPF应用程序,它具有可以加载和保存的当前项目。 当前项目设置在整个应用程序中使用…

我在代码中留下了所有“噪音”,因为有些人可能觉得它很有用。

 class Settings : INotifyPropertyChanged { private static Settings _currentSettings = new Settings(); ///  The one and only Current Settings that is the current Project.  [JsonIgnore] // so it isn't serialized by JSON.NET public static Settings CurrentSettings // https://csharpindepth.com/Articles/General/Singleton.aspx { get { return _currentSettings; } // setter is to load new settings into the current settings (using JSON.NET). Hey, it works. Probably not thread-safe. internal set { Log.Verbose("CurrentSettings was reset. Project Name: {projectName}", value.ProjectName); _currentSettings = value; _currentSettings.IsChanged = false; NotifyStaticPropertyChanged("CurrentSettings"); } } // https://10rem.net/blog/2011/11/29/wpf-45-binding-and-change-notification-for-static-properties ///  Fires when the Curent CurrentTvCadSettings is loaded with new settings /// Event queue for all listeners interested in StaticPropertyChanged events.  public static event EventHandler StaticPropertyChanged = delegate { }; private static void NotifyStaticPropertyChanged(string propertyName) { StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName)); } // various instance properties including .... public string ProjectName {get; set;} [JsonIgnore] public bool IsChanged { get; set; } } 

用于将单例settings为新加载的项目, settings很简单

 Settings settings = new Settings(); // load, save, deserialize, set properties, go nuts Settings.CurrentSettings = settings; 

setter可能不是线程安全的,但我只是在UI线程的一个地方设置它所以我不害怕。 您可以按照https://csharpindepth.com/Articles/General/Singleton.aspx上尊敬的建议使其安全线程安全

我意识到OP没有询问WPF,但我认为显示为什么你可能想要设置单例是相关的。 我这样做是因为它是最简单的解决方案。

使用lambda样式(> = C#6)称为计算属性(也称为表达式成员)来包装+替代语法:

代码在function上完全等同于Jon Skeet的答案,这里再次使用“Instance”。 我不希望得到这样的赞誉,但我认为这个更新的包装在一个地方有解释是值得的,因为这个C#6的问题和答案扩展了旧的封闭线程,其中讨论了Singleton的变体。

您可以认为具有显式缺失集的自动属性样式表示更清晰的只读属性的意图,但最终它是基于样式的,并且这两种样式在现代C#中很常见。

 public sealed class MySingleton { public static MySingleton Instance => new MySingleton(); // Assure that instantiation is only done once (because of static property) and in threadsafe way, and as this is an alternative style for a readonly-property, there is no setter private MySingleton() {} // Assure, that instantiation cannot be done from outside the class static MySingleton() {} // Assure partly lazyness, see below } 

以下是一个地方的所有细节和历史参考:

关于懒惰的讨论: http : //csharpindepth.com/Articles/General/Beforefieldinit.aspx
简化摘要:只要在类中没有引入其他静态字段/属性,上述实现就会变得很懒惰。 (但这是一个可以依赖.NET实现的领域。)

讨论Singleton和线程安全的不同实现(较旧的C#样式): http : //csharpindepth.com/Articles/General/Singleton.aspx

原始线程(关闭): C#的单例模式

上述就是C#学习教程:使用自动属性实现单例是一个好主意吗?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1043416.html

(0)
上一篇 2022年1月31日
下一篇 2022年1月31日

精彩推荐