Singleton:我如何第一次实例Singleton?

时间:2017-06-12 11:05:25

标签: c# singleton

我有这个单身人士课程:

public class Utente
{
    private static readonly Lazy<Utente> lazy =
    new Lazy<Utente>(() => new Utente());

    public static Utente Instance
    {
        get
        {
            return lazy.Value;
        }
        set
        {

        }
    }

    public string name { get; set; }
    public string lastname { get; set; }
    public int id { get; set; }
    public int issuperuser { get; set; }
    public string persontype { get; set; }
    public int idpersontype { get; set; }
    public string token { get; set; }
    public string[] permissions { get; set; }
    public List<Mese> mese { get; set; }
}

我需要第一次懒惰。我怎么做?我需要第一次将类保存到整个程序的其余部分。

现在我需要在这个课程中使用它:

Utente u = new Utente();
WebRequest richiesta = (HttpWebRequest)WebRequest.Create(URL);
WebResponse risposta = (HttpWebResponse)CreateLoginRequest(richiesta).GetResponse();
StreamReader dati = new StreamReader(risposta.GetResponseStream());
string output = dati.ReadToEnd();
u = JsonConvert.DeserializeObject<Utente>(output);
risposta.Close();

Utente()是正确的还是我应该使用其他代码? 编辑:

Utente u = new Utente();
WebRequest richiesta = (HttpWebRequest)WebRequest.Create(URL);
WebResponse risposta = (HttpWebResponse)CreateLoginRequest(richiesta).GetResponse();
StreamReader dati = new StreamReader(risposta.GetResponseStream());
string output = dati.ReadToEnd();
u = JsonConvert.DeserializeObject<Utente>(output);
risposta.Close();

该类Utente只需要实例化一次,以便我可以在所有程序中使用该值。那么,为什么我在另一个班级做这个:`

if (verifica && (Utente.Instance.persontype == "Datore")) 

Utente.Instance.persontype结果为null?

4 个答案:

答案 0 :(得分:2)

第一个问题:您尚未通过公共构造函数禁用Utente类实例创建。代码的第一行创建一个新实例:

Utente u = new Utente();

正如其他人已经提到的那样,你必须禁止在这个类之外创建单例类的新实例。使构造函数成为私有的:

private Utente() { }

现在第二个问题 - 你想用Newtonsoft JSON反序列化器填充单例的属性。 即使构造函数是私有的,每次反序列化一些字符串时,反序列化器都会创建一个新的Utrente类实例:

var newInstance = JsonConvert.DeserializeObject<Utente>(output); // 'output' is json string

所以你不应该使用DeserializeObject方法。你应该使用PopulateObject方法并传递已经存在的单例实例,由Newtonsoft JSON填充:

JsonConvert.PopulateObject(output, Utente.Instance); 

小注意事项 - 对于singleton的set属性,您不需要Instance方法。使用C#6 Expression-Bodied成员,您可以将此属性简化为:

public static Utente Instance => lazy.Value;

答案 1 :(得分:0)

你已经实例化了lazy,它在这一行中被实例化:

private static readonly Lazy<Utente> lazy = new Lazy<Utente>(() => new Utente());

每当你在懒惰上调用.Value时,它将确保调用constuctor并存储并返回实例。从您的代码中,懒惰的人无法返回null

旁注:你通常在单例模式中没有setter,它应该自我初始化。

您的代码中的问题是您正在从单例类外部创建一个新实例:Utente u = new Utente();。这就是单身人士的工作方式。您只能访问Utente.Instance。您可以通过向Utente类添加私有构造函数来阻止从外部实例化实例:

private Utente
{ }

根据您当前的代码,您似乎根本不应该使用单例模式,因为您尝试从JSON流反序列化它:可能有多个实例。

答案 2 :(得分:0)

改变你的班级:

public class Utente
{
    private static readonly Lazy<Utente> lazy =
    new Lazy<Utente>(() => new Utente());

    // private C'tor - prevent from other to create your class
    private Utente() { }
    // Give access to your instnace
    public static Utente Instance
    {
        get
        {
            return lazy.Value;
        }
    }

答案 3 :(得分:0)

这里你做错了

Utente u = new Utente();

而不是实例化Utente使用

Utente u = Utente.Instance;

但是,您应该定义私有构造函数,以便可以防止另一个实例被实例化。

public class Utente
{
    private Utente(){} //override default public constructor.
    private static readonly Lazy<Utente> lazy =
    new Lazy<Utente>(() => new Utente());

    public static Utente Instance
    {
        get
        {
            return lazy.Value;
        }
        set
        {

        }
    }

    public string name { get; set; }
    public string lastname { get; set; }
    public int id { get; set; }
    public int issuperuser { get; set; }
    public string persontype { get; set; }
    public int idpersontype { get; set; }
    public string token { get; set; }
    public string[] permissions { get; set; }
    public List<Mese> mese { get; set; }
}