如何在C#中销毁静态类

时间:2009-02-10 06:05:23

标签: c#

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

我想找到一种简单的方法来销毁这个类,而不是逐个重置每个变量。例如,如果有一个静态类MyStatic,我本来希望通过写MyStatic = null来破坏/删除这个类,这是目前无法实现的,

其他问题。

单身人士的想法很好,但我有以下问题:

如果实现单例,“单个”对象仍将保留在内存中。在单例中,我们只检查实例是否已存在。我怎样才能确保此实例变量也被破坏。

我有一个主类,用于初始化静态类中的变量。即使我计划实现Rest()方法,我也需要从一个方法中调用它,例如,主类中的析构函数。但是只有当GC在内存中收集这个主类对象时才会调用此析构函数,这意味着Reset()被调用很晚

感谢 普拉迪普

10 个答案:

答案 0 :(得分:18)

不要使用静态类来存储变量。使用一个实例(如果你在任何给定的时间只想要一个实例,那就使它成为单例。)然后你可以实现IDisposible,并在你想要销毁它时调用Dispose()。

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

编辑

该对象仍然需要进行垃圾回收,因此除非您使用大量非托管资源,否则您应该没问题。您可以实现IDisposible来清理任何需要清理的资源。

答案 1 :(得分:9)

而不是静态类,有一个类的静态实例:

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;
}

答案 2 :(得分:6)

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

编辑:补充问题

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

答案 3 :(得分:2)

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

答案 4 :(得分:2)

你破坏对象,而不是类。静态类没有任何问题--C#提供它们是有原因的。单身人士只是额外的开销,除非你真的需要一个对象,例如当你必须将对象作为参数传递时。

静态类仅包含静态变量。这些变量往往会持续应用程序的生命周期,在这种情况下,您不必担心处置引用的对象,除非您有一个温和的OCD案例。这就是静态类在其生命周期中分配和释放资源的情况。像往常一样在适当的时候处理这​​些物体(例如,“使用......”)。

答案 5 :(得分:1)

你的条件最好的方法是内置一个Reset()方法,它可以重置类的值。

答案 6 :(得分:1)

class myclass

{

private static myclass singleobj = null;
private myclass(){}
public static myclass CreateInstance()
{
if(singleobj == null)
  singleobj =  new myclass();

return singleobj
}

}

答案 7 :(得分:1)

以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
}

(未经测试......但大多数是正确的,我认为) 您还可以添加IDispose接口的使用以进行更多清理。

答案 8 :(得分:0)

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

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;
    }
}

答案 9 :(得分:0)

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

确保实现类似“Disable()”的内容,以便让静态类知道它的对象刚被设置为null。

例如,我有一个记录器类,如下所示:

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);