C# 当使用单例模式时,我的public类应该返回private还是public实例?

C# 当使用单例模式时,我的public类应该返回private还是public实例?,c#,xamarin.ios,garbage-collection,xamarin.android,automatic-ref-counting,C#,Xamarin.ios,Garbage Collection,Xamarin.android,Automatic Ref Counting,我有一个单件的定义如下: public partial class MoonDataManager { static MoonDataManager _singletonInstance; public static MoonDataManager SingletonInstance { get { return _singletonInstance; } private set

我有一个单件的定义如下:

public partial class MoonDataManager
{

    static MoonDataManager _singletonInstance;
    public static MoonDataManager SingletonInstance
    {
        get
        {
            return _singletonInstance;
        }
        private set
        {
            _singletonInstance = value;
        }
    }
我有一个安全创建实例的函数:

   public static async Task<MoonDataManager> CreateSingletonAsync()
    {
            _singletonInstance = new MoonDataManager();

我关心垃圾收集,特别是在Xamarin中的iOS或Android中

此外,如果在C#中有这种命名模式,请告诉我是否偏离了标准


更新:

现在我想我真的被线程和异步方法困住了。以下是对象及其目标:

  • MoonDataManager
    :对每个表运行一次
    注册表。这是一个基本上运行
    (新MobileServiceSQLiteStore)的通用方法。DefineTable()

  • OfflineStore
    :这是一个
    MobileServiceSQLiteStore

  • MobileClient
    :这是一个
    MobileServiceClient

  • MoonDataManager
    依赖项:MoonDataManager需要离线存储和MobileClient来完成初始化。具体来说,它执行一个
    MobileServiceClient
    .SyncContext.InitializeAsync(
    OfflineStore

我不知道如何理解这种依赖的意大利面。。。或者如何使代码看起来漂亮,并且是线程安全的

下面是代码的新迭代:

private readonly Lazy<MobileServiceClient> lazyMobileClient = 
        new Lazy<MobileServiceClient>(() => new MobileServiceClient(Constants.ApplicationURL), true); // true for thread safety
    public  MobileServiceClient MobileClient { get { return lazyMobileClient.Value; } }


    private readonly Lazy< MobileServiceSQLiteStore> offlineDB =
        new Lazy<MobileServiceSQLiteStore>(() =>  new MobileServiceSQLiteStore(Constants.OfflineDBName), true ); // true for thread safety
    private MobileServiceSQLiteStore OfflineStore { get { return offlineDB.Value; } }

    private static readonly Lazy<MoonDataManager> lazy =  new Lazy<MoonDataManager>(() => new MoonDataManager(), true); // true for thread safety
    public static MoonDataManager Instance { get { return lazy.Value; } }

    private MoonDataManager()
    {

             MoonDataManager.Instance.RegisterTable<Models.IssuerKey>();

            // Initialize file sync
            // todo: investigate FileSyncTriggerFactory overload. 
            //Was present on Mar 30, 2016 Channel9  https://channel9.msdn.com/events/Build/2016/P408
            MoonDataManager.Instance.MobileClient.InitializeFileSyncContext
                           (new IssuerKeyFileSyncHandler(Instance),   Instance.OfflineStore);

            // NOTE THE ASYNC METHOD HERE (won't compile)
            await MoonDataManager.Instance.MobileClient
                                 .SyncContext.InitializeAsync(MoonDataManager.Instance.OfflineStore,
                                StoreTrackingOptions.NotifyLocalAndServerOperations);

    }
private只读lazyMobileClient=
new Lazy(()=>new MobileServiceClient(Constants.ApplicationURL),true);//对于线程安全来说,这是正确的
public MobileServiceClient MobileClient{get{return lazyMobileClient.Value;}}
私有只读延迟offlineDB=
new Lazy(()=>new MobileServiceSQLiteStore(Constants.OfflineDBName),true);//对于线程安全来说,这是正确的
私有MobileServiceSQLiteStore离线存储{get{return offlineDB.Value;}}
private static readonly Lazy Lazy=new Lazy(()=>new MoonDataManager(),true);//对于线程安全来说,这是正确的
公共静态MoonDataManager实例{get{return lazy.Value;}}
私有数据管理器()
{
MoonDataManager.Instance.RegisterTable();
//初始化文件同步
//todo:调查FileSyncTriggerFactory过载。
//于2016年3月30日出席第9频道https://channel9.msdn.com/events/Build/2016/P408
MoonDataManager.Instance.MobileClient.InitializeFileSyncContext
(新的IssuerKeyFileSyncHandler(实例),Instance.OfflineStore);
//注意这里的异步方法(不会编译)
等待MoonDataManager.Instance.MobileClient
.SyncContext.InitializeAsync(MoonDataManager.Instance.OfflineStore,
StoreTrackingOptions.NotifyLocal和ServerOperations);
}

您应该返回私有实例。您可以在上阅读有关单例模式的更多信息。标准单例实现如下所示:

public class Singleton
{
    private static Singleton instance;

    private Singleton() {}

    public static Singleton Instance
    {
       get 
       {
          if (instance == null)
          {
             instance = new Singleton();
          }
          return instance;
       }
    }
}

不过,通常情况下,属性没有setter。此模式具有。

您应该返回私有实例。您可以在上阅读有关单例模式的更多信息。标准单例实现如下所示:

public class Singleton
{
    private static Singleton instance;

    private Singleton() {}

    public static Singleton Instance
    {
       get 
       {
          if (instance == null)
          {
             instance = new Singleton();
          }
          return instance;
       }
    }
}
不过,通常情况下,属性没有setter。此模式具有定义

static MoonDataManager _singletonInstance;
确保
MoonDataManager
的实例是GC根目录,并且在应用程序域结束之前不会收集该实例


我会归还你的私人单身汉,放弃你的汽车财产

public partial class MoonDataManager
{
    private static readonly Lazy<MoonDataManager> _manager = 
        new Lazy<MoonDataManager>(() => new MoonDataManager()); 

    public static MoonDataManager SingletonInstance => _manager.Value; 
}
公共部分类数据管理器
{
专用静态只读惰性_管理器=
new Lazy(()=>new MoonDataManager());
public static MoonDataManager singletonistance=>\u manager.Value;
}
首次访问
MoonDataManager.Value
时,使用传递给
Lazy
构造函数的
Func
对其进行初始化。在后续访问中,将返回相同的实例

定义

static MoonDataManager _singletonInstance;
确保
MoonDataManager
的实例是GC根目录,并且在应用程序域结束之前不会收集该实例


我会归还你的私人单身汉,放弃你的汽车财产

public partial class MoonDataManager
{
    private static readonly Lazy<MoonDataManager> _manager = 
        new Lazy<MoonDataManager>(() => new MoonDataManager()); 

    public static MoonDataManager SingletonInstance => _manager.Value; 
}
公共部分类数据管理器
{
专用静态只读惰性_管理器=
new Lazy(()=>new MoonDataManager());
public static MoonDataManager singletonistance=>\u manager.Value;
}

首次访问
MoonDataManager.Value
时,使用传递给
Lazy
构造函数的
Func
对其进行初始化。在后续访问中,将返回相同的实例

一个单例在第一次被访问时创建自己,这样可以确保只创建一个实例,即使第二个线程试图在它仍在被实例化时访问它

您的CreateSingletonAsync()违反了这一点,并且看起来它允许多线程运行

你想要的是:

public static MoonDataManager SingletonInstance
{
    get
    {
        if (_singletonInsatnce != null)
            return _singletonInstance;
        lock (lockobject)
        {
            // check for null again, as new one may have been created while a thread was waiting on the lock
            if (_singletonInsatnce != null)
                return _singletonInstance;
            else
                // create new one here.
        }
    }
    // no setter, because by definition no other class can instantiate the singleton
}
所有这些只是为了确保请求一个对象的两个线程不会最终创建两个对象,或者如果第一个线程的一个对象仍在创建中,则第二个线程会得到一个半创建的对象

注:单身人士已经不再流行了

注意:如果您可以确保在访问对象之前有时间创建对象,那么您可以使用静态成员并在应用程序启动时创建它


您的问题“我应该返回属性还是字段”没有意义——您已经从属性getter返回了字段,这是标准做法。您还想返回什么?

单例在第一次访问它时创建自己,这样可以确保只创建一个实例,即使第二个线程试图在它仍在实例化时访问它

您的CreateSingletonAsync()违反了这一点