【发布时间】:2015-04-25 13:49:04
【问题描述】:
我一直在尝试实现单例的方法。我编写了一个小的管理对象,它允许使用更简单、更少代码的方法来编写单例类。
我永远不会在生产系统中使用这样的东西,这有几个原因导致我提出我的问题。
使用下面的代码 - 我假设这个实现会/可能导致线程问题和内存泄漏?我说的对吗?
namespace ConsoleApplication1
{
public static class SingletonManager
{
private static readonly Dictionary<string, object> Objects;
static SingletonManager()
{
Objects = new Dictionary<string, object>();
}
public static T InstanceOf<T>(object[] ctorArgs = null)
where T : class
{
var name = typeof (T).FullName;
if (Objects.ContainsKey(name))
return Objects[name] as T;
var ctor = typeof (T).GetConstructors(
BindingFlags.Instance |
BindingFlags.NonPublic)[0];
var instance = ctor.Invoke(ctorArgs) as T;
Objects[name] = instance;
return instance as T;
}
public static void DisposeOf<T>()
where T : Singleton<T>
{
Dispose(typeof (T).FullName);
}
public static void DisposeOf(Type type)
{
Dispose(type.FullName);
}
private static void Dispose(string name)
{
if (!Objects.ContainsKey(name)) return;
var obj = Objects[name];
if (obj is IDisposable)
((IDisposable) Objects[name]).Dispose();
Objects.Remove(name);
}
}
public class Singleton<T>
where T : class
{
private static object ThreadLock = new object();
public static T Instance(object[] ctorArgs = null)
{
lock (ThreadLock)
{
return SingletonManager.InstanceOf<T>(ctorArgs);
}
}
}
public class SomeSingletonClass : Singleton<SomeSingletonClass>
{
public int Number;
private SomeSingletonClass(int i)
{
Number = i;
}
}
internal class Program
{
private static void Main(string[] args)
{
var instance1= SomeSingletonClass.Instance(new object[] {1});
var instance2 = SomeSingletonClass.Instance(new object[] { 2 });
//Is false
var updated = instance1.Number == 2;
instance2.Number = 99;
//Is true
var equals = instance1.Number == instance2.Number;
//Is true
var refEquals = ReferenceEquals(instance1, instance2);
Debugger.Break();
}
}
}
【问题讨论】:
-
为什么是单身经理?单例应该很少见,并且使用
Lazy<T>很容易实现。 -
是的,这是真的。正如我所说,我永远不会在实际系统中使用这样的东西。我今天只是在一个项目中查看一些旧代码,该项目使用了很多单例类,并希望通过简单的实现来玩一玩。
-
您可能应该改用 CodeReview codereview.stackexchange.com。除非对象实现 IDisposable,否则我会避免命名诸如 Dispose 之类的方法。
标签: c# multithreading memory-leaks singleton