gpt4 book ai didi

c# - 单例与 GetSafeUninitializedObject

转载 作者:太空宇宙 更新时间:2023-11-03 19:18:06 25 4
gpt4 key购买 nike

我遇到了 this Marc Gravell 关于如何在不调用其构造函数的情况下创建对象的回答。有人可以确认这甚至不会规避单例模式的完整和最佳实现(引用实现 here 。为什么?我想更具体地说,我不清楚 GetSafeUninitializedObject() 在类构造函数的上下文中的内部工作原理(静态、私有(private)等)

最佳答案

在单例模式中,您的类型有一个静态变量,它将由类型构造函数初始化。

通过调用 GetSafeUninitializedObject,您只需避免实例构造函数,它将在 类型构造函数 之后调用。

例子:

public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private static string _StaticMessage = "Type ctor;";

private string _Message = "init; ";

static Singleton()
{ }

private Singleton()
{
_Message += "ctor; ";
}

public static Singleton Instance
{
get { return instance; }
}

public string Message { get { return _StaticMessage + _Message; } }
}

internal class Program
{
private static void Main(string[] args)
{
var singleton = Singleton.Instance;
// writes "Type ctor;init; ctor;"
Console.WriteLine(singleton.Message);

var instance = (Singleton)System.Runtime.Serialization.FormatterServices
.GetSafeUninitializedObject(typeof(Singleton));

// writes "Type ctor;"
Console.WriteLine(instance.Message);
}
}

更新以阐明 IllidanS4 要求的类型初始化器和静态构造器之间的区别

这实际上并不属于上面的答案,而是属于评论中的问题:答案根本不适合简单的评论。

@IllidanS4:类型初始值设定项只是编写隐式静态构造函数的捷径。如果您创建一个包含两种初始化方法的类并反编译生成的程序集,您只能看到一个将初始化所有变量的静态构造函数 (.cctor)。这两个赋值将被合并,其中首先调用类型初始值设定项,最后调用静态构造函数中的语句。

参加这个示例类(class):

internal static class C
{
public static readonly string ByTypeCtor;
public static readonly string ByTypeInitializer = "From type init; ";
public static string ByBoth = "From type init; ";

static C()
{
ByTypeCtor = "From static ctor; ";
ByBoth += "From static ctor";
}
}

如果你编译它然后反编译它(例如通过使用 ILSpy )你会得到以下代码:

internal static class C
{
public static readonly string ByTypeCtor;
public static readonly string ByTypeInitializer;
public static string ByBoth;
static C()
{
C.ByTypeInitializer = "From type init; ";
C.ByBoth = "From type init; ";
C.ByTypeCtor = "From static ctor; ";
C.ByBoth += "From static ctor";
}
}

由于这个事实,我通常不会在声明变量时直接初始化变量。相反,我总是让它们保持未初始化状态(如 ByTypeCtor 变量)并在构造函数中进行所有初始化。这只是避免了将变量初始化困惑到类中的不同位置,从而提高了可维护性。

关于c# - 单例与 GetSafeUninitializedObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14585029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com