代码之家  ›  专栏  ›  技术社区  ›  pradeeptp

如何销毁C中的静态类#

c#
  •  18
  • pradeeptp  · 技术社区  · 16 年前

    我使用的是.net 1.1。我有一个会话类,其中存储了许多静态变量,这些变量保存了许多类要使用的数据。

    单例的想法很好,但我有以下问题:

    如果实现了singleton,那么“single”对象仍将保留在内存中。在单例中,我们只检查实例是否已经存在。我如何确保这个实例变量也被销毁。

    谢谢 普拉迪普

    10 回复  |  直到 16 年前
        1
  •  19
  •   Kyle Trauberman pestades    14 年前

    不要使用静态类来存储变量。使用一个实例(如果在任何给定时间只需要一个实例,则将其设置为单例。)然后,您可以实现IDispoible,并在想要销毁它时调用Dispose()。

    有关更多信息,请查看此网站: http://csharpindepth.com/Articles/General/Singleton.aspx

    编辑

        2
  •  9
  •   ChrisW    16 年前

    使用类的静态实例而不是静态类:

    class Foo
    {
      public int Something;
      public static Foo Instance = new Foo();
      public void Reset()
      {
        Instance = new Foo();
      }
    }
    
    void test
    {
      int i = Foo.Instance.Something;
    }
    

    您还可以委托给类的一个实例:

    class Foo
    {
      public int Something
      {
        get { return instance.something; }
      }
      private int something;
      private static Foo instance = new Foo();
      public void Reset()
      {
        instance = new Foo();
      }
    }
    
    void test
    {
      int i = Foo.Something;
    }
    
        3
  •  6
  •   Brian Rasmussen    16 年前

    除非静态驻留在单独的AppDomain中,否则无法销毁它,在这种情况下,您可以通过卸载AppDomain来删除它。然而,通常最好避免静校正。

    编辑:附加问题

    当单例不再被引用时,它将像其他所有东西一样被收集。换句话说,如果你想收集它,你必须确保没有对它的引用。不言而喻,如果你存储对单例的静态引用,你会遇到和以前一样的问题。

        4
  •  2
  •   Soviut    16 年前

    使用像ktrauberman所说的Singleton,并具有初始化方法或重置方法。您只需编写一次代码并调用该方法。

        5
  •  2
  •   user2831877    12 年前

    你破坏的是对象,而不是类。静态类没有什么错——C#提供静态类是有原因的。Singleton只是额外的开销,除非你真的需要一个对象,例如当你必须将对象作为参数传递时。

    静态类只包含静态变量。这些变量往往会持续应用程序的生命周期,在这种情况下,除非你有轻微的强迫症,否则你不必担心处理引用的对象。这只剩下静态类在其整个生命周期内分配和释放资源的情况。在适当的时候像往常一样处理这些物品(例如,“使用…”)。

        6
  •  1
  •   Vaibhav    16 年前

        7
  •  1
  •   Ahmed    16 年前
    class myclass
    
    {
    
    private static myclass singleobj = null;
    private myclass(){}
    public static myclass CreateInstance()
    {
    if(singleobj == null)
      singleobj =  new myclass();
    
    return singleobj
    }
    
    }
    
        8
  •  1
  •   abelenky    16 年前

    以Ahemd Said的回答为基础:(并支持他!)

    class Singleton
    {
        private static Singleton instance  = null;
        private Singleton(){}   // private constructor: stops others from using
    
        public static Singleton Instance
        {
            get { return instance ?? (instance = new Singleton()); }
            set {
                    if (null != value)
                    { throw new InvalidValueException(); }
                    else
                    { instance = null; }
                }
        }
    }
    
    
    void SampleUsage()
    {
        Singleton myObj = Singleton.Instance;
        // use myObj for your work...
        myObj.Instance = null;  // The set-operator makes it ready for GC
    }
    

        9
  •  0
  •   Sarath Subramanian    11 年前

    您可以在静态类中创建一个方法,重置所有属性的值。

    public static class ClassA
    {
         public static int id=0;
         public static string name="";
    
         public static void ResetValues()
         {
             // Here you want to reset to the old initialized value
             id=0;
             name="";
         }
    }
    

    现在,您可以从任何其他类中使用以下任何方法来重置静态类的值

    方法1-直接呼叫

    ClassA.ResetValues();
    

    方法2-从已知名称空间和已知类动态调用方法

    Type t1 = Type.GetType("Namespace1.ClassA");
    MethodInfo methodInfo1 = t1.GetMethod("ResetValues");
    if (methodInfo1 != null)
    {
         object result = null;
         result = methodInfo1.Invoke(null, null);                
    }
    

    方法3-从程序集/程序集动态调用方法

    foreach (var Ass in AppDomain.CurrentDomain.GetAssemblies())
    {
         // Use the above "If" condition if you want to filter from only one Dll
         if (Ass.ManifestModule.FullyQualifiedName.EndsWith("YourDll.dll"))
         {
                List<Type> lstClasses = Ass.GetTypes().Where(t => t.IsClass && t.IsSealed && t.IsAbstract).ToList();
                foreach (Type type in lstClasses)
                {
                      MethodInfo methodInfo = type.GetMethod("ResetValues");
                      if (methodInfo != null)
                      {
                           object result = null;
                           result = methodInfo.Invoke(null, null);                                
                      }
                 }
                 break;
        }
    }
    
        10
  •  0
  •   rollsch    8 年前

    在启动时从实现IDisposable的非静态类将对象注入静态类中,然后在非静态类被销毁时,静态类使用的对象也被销毁。

    确保实现类似“Disable()”的东西,这样静态类就会知道它的对象刚刚被设置为null。

    例如,我有一个logger类,如下所示:

    public static class Logger
    {
        private static Action<string, Exception, bool> _logError;
    
        public static void InitLogger(Action<string, Exception, bool> logError)
        {
            if(logError != null) _logError = logError;
        }
    
        public static void LogError(string msg, Exception e = null, bool sendEmailReport = false)
        {
            _logError?.Invoke(msg, e, sendEmailReport);
        }
    

    在Form的构造函数中,我调用以下命令来设置记录器。

    Logger.InitLogger(LogError);
    

    然后,在我的项目中的任何一节课上,我都可以做以下事情:

    Logger.LogError("error",new Exception("error), true);