Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在同一个应用程序中是否有两个不同的单例? 如果我考虑单例的基本实现,例如: private static Foo instance; private readonly static Object SyncRoot=new Object(); public static Foo Instance { get { if(instance!=null) return instance; lock(SyncRoot) { if(instance!=null) { return instance; } instance=new Foo(); return instance; } } }_C#_Singleton - Fatal编程技术网

C# 在同一个应用程序中是否有两个不同的单例? 如果我考虑单例的基本实现,例如: private static Foo instance; private readonly static Object SyncRoot=new Object(); public static Foo Instance { get { if(instance!=null) return instance; lock(SyncRoot) { if(instance!=null) { return instance; } instance=new Foo(); return instance; } } }

C# 在同一个应用程序中是否有两个不同的单例? 如果我考虑单例的基本实现,例如: private static Foo instance; private readonly static Object SyncRoot=new Object(); public static Foo Instance { get { if(instance!=null) return instance; lock(SyncRoot) { if(instance!=null) { return instance; } instance=new Foo(); return instance; } } },c#,singleton,C#,Singleton,在同一个应用程序中是否有两个不同的单例?使用反射、执行和同步上下文、appdomain类或任何其他类型的魔法动态加载dll 是的,可以使用反射,您的代码只应用于属性,反射可以创建没有属性的Foo实例 ConstructorInfo ctor = typeof(Foo).GetConstructors (BindingFlags.Instance | BindingFlags.NonPublic)[0]; Foo foo = (Foo) ctor.Invoke(null); 是

在同一个应用程序中是否有两个不同的单例?使用反射、执行和同步上下文、appdomain类或任何其他类型的魔法动态加载dll

是的,可以使用反射,您的代码只应用于属性,反射可以创建没有属性的Foo实例

ConstructorInfo ctor = typeof(Foo).GetConstructors
        (BindingFlags.Instance | BindingFlags.NonPublic)[0];

Foo foo = (Foo) ctor.Invoke(null);

是的,反射是可能的,您的代码只应用于属性,反射可以创建没有属性的Foo实例

ConstructorInfo ctor = typeof(Foo).GetConstructors
        (BindingFlags.Instance | BindingFlags.NonPublic)[0];

Foo foo = (Foo) ctor.Invoke(null);

您必须定义同一应用程序的含义。如果一个应用程序可以跨越多个AppDomain,那么是的——每个AppDomain实际上都有一个完全独立的Foo类。同样,如果您有使用反射将实例字段重置为null的受信任代码,那么您将很容易得到两个实例:

var field = typeof(Foo).GetField("instance",
                                 BindingFlags.Static | BindingFlags.NonPublic);

var foo1 = Foo.Instance;
field.SetValue(null, null);
var foo2 = Foo.Instance;
foo1和foo2都将是非null的不同引用。或者正如gdoron的回答所提到的,代码也可以通过反射调用可能是私有的构造函数

在单个AppDomain中,并且没有任何故意造成问题的情况下,您应该不会有问题


请注意,无论如何我都不推荐这种单例模式的实现。我通常只使用静态初始值设定项,以使生活更简单。有关更多详细信息,请参阅my。

您必须定义同一应用程序的含义。如果一个应用程序可以跨越多个AppDomain,那么是的——每个AppDomain实际上都有一个完全独立的Foo类。同样,如果您有使用反射将实例字段重置为null的受信任代码,那么您将很容易得到两个实例:

var field = typeof(Foo).GetField("instance",
                                 BindingFlags.Static | BindingFlags.NonPublic);

var foo1 = Foo.Instance;
field.SetValue(null, null);
var foo2 = Foo.Instance;
foo1和foo2都将是非null的不同引用。或者正如gdoron的回答所提到的,代码也可以通过反射调用可能是私有的构造函数

在单个AppDomain中,并且没有任何故意造成问题的情况下,您应该不会有问题


请注意,无论如何我都不推荐这种单例模式的实现。我通常只使用静态初始值设定项,以使生活更简单。有关更多详细信息,请参阅my。

当然,如果您使用不同的AppDomain,那么每个AppDomain将获得一个实例。 我认为,如果您处于多线程环境中,那么使用的锁定机制也可能存在问题。 不要在getter中创建实例,而是使用

private static Foo Instance = new Foo();

当然,如果您使用不同的AppDomain,那么每个AppDomain将获得一个实例。 我认为,如果您处于多线程环境中,那么使用的锁定机制也可能存在问题。 不要在getter中创建实例,而是使用

private static Foo Instance = new Foo();

抗反射单态模式:

public sealed class Singleton
{
    public static Singleton Instance => _lazy.Value;
    private static Lazy<Singleton, Func<int>> _lazy { get; }

    static Singleton()
    {
        var i = 0;
        _lazy = new Lazy<Singleton, Func<int>>(() =>
        {
            i++;
            return new Singleton();
        }, ()=>i);
    }

    private Singleton()
    {
        if (_lazy.Metadata() == 0 || _lazy.IsValueCreated) 
            throw new Exception("Singleton creation exception");
    }

    public void Run()
    {
        Console.WriteLine("Singleton called");
    }
}

抗反射单态模式:

public sealed class Singleton
{
    public static Singleton Instance => _lazy.Value;
    private static Lazy<Singleton, Func<int>> _lazy { get; }

    static Singleton()
    {
        var i = 0;
        _lazy = new Lazy<Singleton, Func<int>>(() =>
        {
            i++;
            return new Singleton();
        }, ()=>i);
    }

    private Singleton()
    {
        if (_lazy.Metadata() == 0 || _lazy.IsValueCreated) 
            throw new Exception("Singleton creation exception");
    }

    public void Run()
    {
        Console.WriteLine("Singleton called");
    }
}


我认为如果您使用不同的AppDomain,这是可能的。但需要验证这一点。从技术上讲,若你们不声明实例是易变的,这是可能的。这不是偶然的,打折应用程序域。你不是想这么做吧?你确实有一个用于Foo的私有构造函数,对吗?否则,任何人都可以创建任意多的实例…我认为如果您使用不同的AppDomain,这是可能的。但需要验证这一点。从技术上讲,若你们不声明实例是易变的,这是可能的。这不是偶然的,打折应用程序域。你不是想这么做吧?你确实有一个用于Foo的私有构造函数,对吗?否则,任何人都可以创建任意多的实例……反射更容易,不是吗?@gdoron:是的,只是编辑了一下而已。现在提供了示例代码。哈哈,非常好,将instance设置为null。。。但是简单地调用ctor更容易+1.@JonSkeet谢谢你的回复!但是我有一个问题,我的应用程序有两个单例,当我收到来自WCF服务的第一个调用时,这种情况就发生了。同一个应用程序,一些关于为什么会发生这种情况的提示?@J.Lennon:Yup-因为如果两个类型在不同的程序集中,它们只是不同的类型。反射更容易,不是吗?@gdoron:Yup,我只是在编辑。现在提供了示例代码。哈哈,非常好,将instance设置为null。。。但是简单地调用ctor更容易+1.@JonSkeet谢谢你的回复!但是我有一个问题,我的应用程序有两个单例,当我收到来自WCF服务的第一个调用时发生了同样的应用程序,这是为什么会发生的一些提示?@J.Lennon:Yup-因为如果两种类型在不同的程序集中,它们只是不同的类型。噢,我甚至没有想过通过反射调用可能是私有的构造函数。我试图将字段设置回null——请参阅示例代码的答案。这可能看起来很奇怪,但如果我加载/调用两个不同文件路径的相同程序集。对于同一个类,即使使用实例,它也会抛出两个单例property@J.Lennon. 为什么要使用反射呢?不能使用,因为它引用了屁股
embly?@gdoron将使用我的singleton的类是动态加载的,因为抽象/internface,我需要模拟代码的行为而不改变原始应用程序。哦,我甚至没有想到通过反射调用可能是私有的构造函数。我试图将字段设置回null——请参阅示例代码的答案。这可能看起来很奇怪,但如果我加载/调用两个不同文件路径的相同程序集。对于同一个类,即使使用实例,它也会抛出两个单例property@J.Lennon. 为什么要使用反射呢?无法使用对程序集的引用吗?@gdoron将使用我的singleton的类是动态加载的,因为存在抽象/内部面,我需要在不更改原始应用程序的情况下模拟代码的行为