实用的泛型Singleton类

本文介绍了一种使用泛型实现的Singleton模式,通过反射调用构造函数来创建对象实例。此方法支持公共或私有构造函数,并展示了如何为Tuple类添加获取空对象的方法,以便简化控件迭代函数的使用。
  Singleton模式是最常的设计模式之一,我们会经常写这类代码.因其基本原理就是保存一个静态的对象实例,所以我们便能利用泛型写出一个通用的Singleton类. 
  代码很简单:
  public   class  Singleton < T >  
    
{
        
static readonly T _t;
        
static Singleton()
        
{
            _t 
= Construct();
        }


        
public static T GetInstance()
        
{
            
return _t;
        }


        
private static T Construct()
        
{
            Type type 
= typeof(T);
            ConstructorInfo ctor;
            ctor 
= type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                                        
nullnew Type[0], new ParameterModifier[0]);
            System.Diagnostics.Debug.Assert(ctor 
!= null"Error in ENLS.Basic.Singleton.Construct().");
            
return (T)ctor.Invoke(new object[0]);            
        }

    }
因为特化的泛型类是不同的类型,Singleton<Tuple<int>>和Singleton<Tuple<int,long>>不同,所以这两个类中的_t是不同的静态实例.然后在Construct方法中通过反射调用共有或私有的默认构造参数来创建新实例.为什么会有public的构造函数呢,这是为了使用NullObject模式.比如为了方便我要给Tuple基类添加一个方法用来的到空对象
 public static Tuple GetNullInstance<_Tuple>() where _Tuple: Tuple
 {
     return Singleton<_Tuple>.GetInstance();
 }
有了这个空对象我就可以更简单的使用前面文章中介绍的遍历控件的函数.
public  IEnumerable < Control >  Iterator < _Tuple > (Control baseCtl)  where  _Tuple : Tuple
        
{
            Tuple tuple 
= Tuple.GetNullInstance<_Tuple>();
            
foreach(Control c in baseCtl.Controls)
            
{
                
if (!tuple.HasType(c))
                
{
                    
foreach (Control c1 in Iterator<_Tuple>(c))
                        
yield return c1;
                }

                
else
                    
yield return c;
            }

        }
这样就可以很方便的调用了
foreach  (Control c  in   this .Iterator < Tuple < TextBox, TreeView, CheckBox >> ( this ))
                MessageBox.Show(c.Name);
### C# 实现单例模式示例 在 C# 中,使用实现单例模式是一种优雅且高效的方式。以下是一个完整的实现示例: ```csharp using System; public class Singleton<T> where T : new() { private static readonly Lazy<T> _instance = new Lazy<T>(() => new T()); public static T Instance { get { return _instance.Value; } } } ``` 此代码定义了一个通用的单例 `Singleton<T>`,其中 `T` 是参数[^2]。通过 `Lazy<T>` 的使用,确保了线程安全和延迟初始化。`new()` 约束保证了 `T` 必须有一个无参构造函数。 以下是使用该单例模式的一个具体示例: ```csharp public class MyJob { private string _timeSpan; private MyJob() { _timeSpan = DateTime.Now.Millisecond.ToString(); } public string Write() { Console.WriteLine(_timeSpan); return _timeSpan; } } class Program { static void Main(string[] args) { for (int i = 0; i < 10; i++) { Console.WriteLine(Singleton<MyJob>.Instance.Write()); } } } ``` 在此示例中,`MyJob` 被设计为单例模式的一部分,其构造函数是私有的,以防止外部实例化[^4]。通过调用 `Singleton<MyJob>.Instance`,可以获取唯一的 `MyJob` 实例。 如果需要更复杂的单例模式(例如基于 Unity 的单例模式),可以参考以下实现: ```csharp using UnityEngine; public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T> { private static T _instance; public static T Instance { get { if (_instance == null) { _instance = FindObjectOfType<T>(); if (_instance == null) { GameObject singletonObject = new GameObject(typeof(T).Name); _instance = singletonObject.AddComponent<T>(); DontDestroyOnLoad(singletonObject); } } return _instance; } } protected virtual void Awake() { if (_instance == null) { _instance = this as T; DontDestroyOnLoad(gameObject); } else if (_instance != this) { Destroy(gameObject); } } protected virtual void OnDestroy() { if (_instance == this) { _instance = null; } } } ``` 此代码片段展示了如何在 Unity 中实现单例模式,适用于游戏开发场景[^3]。 ### 注意事项 - 使用 `Lazy<T>` 可以确保线程安全,并且仅在第一次访问时创建实例。 - 如果需要禁用外部实例化,必须将目标的构造函数设为私有[^1]。 - 在 Unity 中实现单例时,通常需要结合 `DontDestroyOnLoad` 方法以避免场景切换时销毁实例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值