简体   繁体   中英

how to destroy a Static Class in C#

I am using .net 1.1. I have a session class in which I have stored many static variables that hold some data to be used by many classes.

I want to find a simple way of destroying this class instead of resetting every variable one by one. For example if there is a static class MyStatic, I would have liked to destroy/remove this class from the memory by writing MyStatic = null, which is not currently possible,

Additional question.

The idea of singleton is good, but I have the following questions:

If singleton is implemented, the 'single' object will still remain in the memory. In singleton, we are only checking if an instance is already existing. how can i make sure that this instance variable also gets destroyed.

I have a main class which initializes the variable in the static class. Even if I plan to implement a Rest() method, I need to call it from a method, for eg, the destructor in the main class. But this destructor gets called only when GC collects this main class object in the memory, which means the Reset() gets called very late

thanks pradeep

Don't use a static class to store your variables. Use an instance (and make it a singleton if you only want one instance at any given time.) You can then implement IDisposible, and just call Dispose() when you want to destroy it.

For more information check out this site: http://csharpindepth.com/Articles/General/Singleton.aspx

The object is still subject to garbage collection, so unless you are using lots of unmanaged resources, you should be fine. You can implement IDisposible to clean up any resources that need to be cleaned up as well.

Instead of a static class, have a static instance of a class:

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

void test
{
  int i = Foo.Instance.Something;
}

You can also delegate to an instance of the class:

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

There's no way to destroy a static unless it resides in a separate AppDomain in which case you can get rid of it by unloading the AppDomain. However it is usually better to avoid statics.

EDIT: Additional question

When the singleton is no longer referenced it will be collected just as everything else. In other words, if you want it collected you must make sure that there are no references to it. It goes without saying that if you store a static reference to your singleton, you will have the same problem as before.

You destroy objects, not classes. There's nothing wrong with static classes--C# provides them for a reason. Singletons are just extra overhead, unless you actually need an object, eg when you have to pass the object as a parameter.

Static classes contain only static variables. These variables tend to last for the lifetime of the app, in which case you don't have to worry about disposing referenced objects, unless you have a mild case of OCD. That just leaves the case where your static class allocates and releases resources throughout its lifetime. Dispose of these objects in due course as you usually would (eg, "using...").

Use a Singleton like ktrauberman said, and have an initialization method or a reset method. You only have to write the code once and call the method.

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

class myclass

{

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

return singleobj
}

}

Building on Ahemd Said's answer: (and props to him!)

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
}

(untested... but mostly right, I think) You could also add in usage of the IDispose interface for more cleanup.

You can create a method in the static class which resets the values of all properties. Consider you have a static class

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

Now you can use any of the below approaches from any other class to reset value of a static class

Approach 1 - Calling directly

ClassA.ResetValues();

Approach 2 - Invoking method dynamically from a known namespace and known class

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

Approach 3 - Invoking method dynamically from an assembly/set of assemblies

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

Inject the objects into the static class at startup from a non static class that implements IDisposable, then when your non static class is destroyed so are the objects the static class uses.

Make sure to implement something like "Disable()" so the static class is made aware it's objects have just been set to null.

Eg I have a logger class as follows:

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

In my constructor of my Form I call the following to setup the logger.

Logger.InitLogger(LogError);

Then from any class in my project I can do the following:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM