如何在 C# 中销毁静态类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/531199/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 07:01:49  来源:igfitidea点击:

how to destroy a Static Class in C#

c#

提问by pradeeptp

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.

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

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,

我想找到一种简单的方法来销毁这个类,而不是一个一个地重置每个变量。例如,如果有一个静态类 MyStatic,我希望通过写入 MyStatic = null 来销毁/从内存中删除这个类,这目前是不可能的,

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

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

thanks pradeep

谢谢普拉迪普

采纳答案by Kyle Trauberman

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.

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

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

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

EDIT

编辑

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.

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

回答by Brian Rasmussen

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.

没有办法销毁静态,除非它驻留在单独的 AppDomain 中,在这种情况下,您可以通过卸载 AppDomain 来摆脱它。然而,通常最好避免静电。

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.

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

回答by Soviut

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.

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

回答by ChrisW

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

回答by Vaibhav

The best way in your condition is to have an Reset() method built-in as well, which can reset the values of the class.

在您的情况下,最好的方法是内置一个 Reset() 方法,它可以重置类的值。

回答by Ahmed Said

class myclass

{

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

return singleobj
}

}

回答by abelenky

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

基于 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
}

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

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

回答by user2831877

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, e.g. when you have to pass the object as a parameter.

您销毁的是对象,而不是类。静态类没有任何问题——C# 提供它们是有原因的。单例只是额外的开销,除非您确实需要一个对象,例如当您必须将对象作为参数传递时。

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 (e.g., "using...").

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

回答by Sarath Avanavu

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

方法 1 - 直接调用

ClassA.ResetValues();

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

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

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

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

回答by rolls

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.

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

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

确保实现诸如“Disable()”之类的东西,以便静态类知道它的对象刚刚设置为空。

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.

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

Logger.InitLogger(LogError);

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

然后从我项目中的任何课程中,我可以执行以下操作:

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