rex的博客

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  21 随笔 :: 0 文章 :: 58 评论 :: 0 引用

利用c#2.0的范型加上一点反射,构造了一个自认为不错的Singleton实现.

 

public class Singleton<T>
    
{
        
protected Singleton()
        
{
             
//Assert class T don't have public constructor
             
//Assert class T have a private/protected parameterless constructor
        }


        
protected static T _instance;
        
public static T Instance()
        
{
            
//Assert class T don't have public constructor
            
//Assert class T have a private/protected parameterless constructor
            
//Assert class T is not abstract and is not an interface

            
if (_instance == null)
            
{
                    _instance 
= (T)Activator.CreateInstance(typeof(T),true);//use reflection to create instance of T
            }

            
return _instance;
        }


        
public void Destroy()
        
{
            _instance 
= default(T);
        }

    }
使用也很方便;例如
class Foo
{
    
private Foo()//must declare,or assert will fail in the singleton class
    {
    }

    
    
public void Bar()
    
{
        
    }

}




void Test()
{
    Singleton
<Foo>.Instance().Bar();
}
甚至可以这样定义一个类:
public class Foo : Singleton<Foo>
{
    
protected Foo()//must declare
    {
    }

    
    
public void Bar()
    
{
        
    }

}





void Test()
{
    Foo.Instance().Bar();
}
posted on 2006-01-12 17:46 rex 阅读(4347) 评论(28) 编辑 收藏

评论

#1楼 2006-01-13 13:54       
不错,有点意思。
 回复 引用 查看   

#2楼 2006-01-13 14:31 edison1024      
_instance = System.Activator.CreateInstance<T>();
 回复 引用 查看   

#3楼 2006-01-13 17:38 rexz[未注册用户]
Activator.CreateInstance<T>()不带任何参数,因此它不能访问保护或者私有的constructor.而希望成为singleton的class必须没有public的构造函数,否则就不能保证用户不会调用new来构造一个实例
 回复 引用   

#4楼 2006-04-05 09:55 newhappy[未注册用户]
太花绍了
 回复 引用   

#5楼 2006-04-05 09:56 newhappy[未注册用户]
而且 thread safe方面 么作
 回复 引用   

坦白的说.....这是一个非常糟糕的实现.......
 回复 引用   

很精彩。
 回复 引用   

为什么要写用 Activator?直接写:

_instance = new T();

就可以了。当然需要加一个模板参数约束:

where T: new()

 回复 引用   

#9楼 2006-05-14 23:42 rexz[未注册用户]
@Andrew Xu
我希望T的new是私有的,否则用户就可能破坏Singleton的设计本意,用new生成"第二个"实例
 回复 引用   

#10楼 2006-05-16 14:28 天下无双      
精彩#@#@
 回复 引用 查看   

#11楼 2006-05-16 14:29 天下无双      
糟糕在什么地方?@deadnight
 回复 引用 查看   

@rexz
问题在于,即使是使用 Activator,仍然不能创建一个只有 private constructor 的对象,这是违反.NET 安全策略,并且会抛出异常的。
 回复 引用   

#13楼[楼主] 2006-05-19 11:32 rex      
@Andrew Xu
你试试就知道是可以的...反射可以获得所有私有/保护成员信息
 回复 引用 查看   

#14楼 2006-05-24 00:09 cokkiy[未注册用户]
为什么不用
_instance = new T();
呢?搞那么花哨?而且用Activator.CreateInstance访问保护成员是不是有问题?虽然反射可以访问保护/私有成员。
 回复 引用   

#15楼 2006-05-24 00:12 cokkiy[未注册用户]
补充一下:_instance = new T(); T()完全可以是私有或保护的成员啊。
 回复 引用   

#16楼[楼主] 2006-05-24 11:45 rex      
@cokkiy
无语,请自己写代码试一下吧
 回复 引用 查看   

#17楼 2006-05-26 12:41 lextm[未注册用户]
主要是没有了
lock(){
}
不知道是不是线程安全。
 回复 引用   

#18楼[楼主] 2006-05-30 10:52 rex      
@lextm
不安全.需要的话应该加上,我要表达的意思是用这种方式给一些类"注入"一些方法,让他们拥有其它功能:)
 回复 引用 查看   

#19楼 2006-06-07 14:11 fxltdwc[未注册用户]
什么花哨阿。先搞清楚单件模式在什么地方使用再说吧
 回复 引用   

#20楼 2006-06-11 13:16 winking[未注册用户]
不错的想法。可以考虑用继承.

public abstract class Singletion<T>
{
protected abstract T CreateInstace();
...
public static T Instance
{
get {
if (_instance == null)
{
_instance = CreateInstance();
}
return _instance;
}
}
}


public class Foo: Singleton<T>
{
protected override Foo CreateInstance()
{
//create object
}
}
 回复 引用   

按照作者的想法,我来完善一个:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Midapexsoft
{
/// <summary>
/// 单件模式Helper类
/// </summary>
/// <typeparam name="T">需要实现单件模式的类型。必须有一个默认的无参构造函数</typeparam>
public abstract class Singleton<T>
{
private static T instatnce;
private static Object o = new object();

public static T Instance
{
get
{
if (instatnce == null)
{
lock (o)
{
if (instatnce == null)
{
//需要使用非公共的无参构造函数,不能使用new T(),因为它不支持非公共的无参构造函数
instatnce = (T)Activator.CreateInstance(typeof(T), true);
}
}
}

return instatnce;
}

}
}
}
 回复 引用   

#22楼 2006-06-18 21:38 flysnow[未注册用户]
public class Foo
{
public static Foo instance = new Foo();

protected Foo() { }
}

这样岂不是很简单
 回复 引用   

#23楼 2006-07-13 11:04 littlestone      
一个好的单件模板实现是一个非常复杂的问题,楼主可参考网上相关讨论,或<<modern C++ design>>(译名:C++设计新思维),相信会给楼主带来很刺激的技术冲击.
 回复 引用 查看   

#24楼[楼主] 2007-03-12 21:48 rex      
@littlestone
这本书我已经看过很多年了:)
 回复 引用 查看   

#25楼 2007-06-07 17:11 Richard[未注册用户]
Dengyangjun ,用你说的继承方法好像不行吧,CreateInstance()是abstract,不是static,不能从Static的Instance property中调用,把CreateInstance()做成static,又失去了使用继承的意义,不知道我说的对不对
 回复 引用   

有点花,玩了技术点
 回复 引用   

#27楼 2008-01-24 14:39 WOW玩家      
///
/// Singleton泛型类
///

///
public sealed class Singleton< T > where T : new()
{
private static T instance = default(T);

private static object lockHelper = new object();

private Singleton() { }

public static T GetInstance()
{
if (instance == null)
{
lock (lockHelper)
{
if (instance == null)
{
instance = new T();
}
}
}

return instance;
}

public void SetInstance(T value)
{
instance = value;
}

}
 回复 引用 查看   

#28楼 2008-04-28 22:42 Stanley.Luo      
哪里要这么复杂.
将instance 声明为static readonly 就解决问题了,既保证单例,也保证线程安全。

protected static readonly T _instance = new T();

public static T Instance()
{
return _instance;
}
这个方法来自《大话设计模式》
 回复 引用 查看