Подтвердить что ты не робот

Как уничтожить статический класс в С#

Я использую .net 1.1. У меня есть класс сеанса, в котором я сохранил много статических переменных, которые содержат некоторые данные, которые будут использоваться многими классами.

Я хочу найти простой способ уничтожить этот класс вместо того, чтобы каждый раз переустанавливать каждую переменную. Например, если есть статический класс MyStatic, мне бы хотелось уничтожить/удалить этот класс из памяти, написав MyStatic = null, что в настоящее время невозможно,

Дополнительный вопрос.

Идея singleton хороша, но у меня есть следующие вопросы:

Если реализован синглтон, в памяти останется еще один объект. В singleton мы проверяем только если экземпляр уже существует. как я могу убедиться, что эта переменная экземпляра также будет уничтожена.

У меня есть основной класс, который инициализирует переменную в статическом классе. Даже если я планирую реализовать метод Rest(), мне нужно вызвать его из метода, например деструктора в основном классе. Но этот деструктор вызывается только тогда, когда GC собирает этот основной объект класса в памяти, что означает, что Reset() вызывается очень поздно

спасибо Прадип

4b9b3361

Ответ 1

Не используйте статический класс для хранения ваших переменных. Используйте экземпляр (и сделайте его одиночным, если вам нужен только один экземпляр в любой момент времени.) Затем вы можете реализовать IDisposible и просто вызвать Dispose(), когда хотите его уничтожить.

Для получения дополнительной информации посетите наш сайт: http://csharpindepth.com/Articles/General/Singleton.aspx

ИЗМЕНИТЬ

Объект по-прежнему зависит от сбора мусора, поэтому, если вы не используете много неуправляемых ресурсов, вы должны быть в порядке. Вы можете реализовать IDisposible для очистки любых ресурсов, которые необходимо очистить.

Ответ 2

Вместо статического класса, есть статический экземпляр класса:

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

Невозможно уничтожить статику, если она не находится в отдельном AppDomain, и в этом случае вы можете избавиться от нее, разгрузив AppDomain. Однако обычно лучше избегать статики.

EDIT: Дополнительный вопрос

Когда синглтон больше не ссылается, он будет собран так же, как и все остальное. Другими словами, если вы хотите его собрать, вы должны убедиться, что на нем нет ссылок. Само собой разумеется, что если вы сохраните статическую ссылку на свой синглтон, у вас будет такая же проблема, как и раньше.

Ответ 4

Используйте Singleton, например ktrauberman, и используйте метод инициализации или метод reset. Вам нужно только написать код один раз и вызвать метод.

Ответ 5

Лучший способ в вашем состоянии - иметь встроенный метод Reset(), который может reset значения класса.

Ответ 6

class myclass

{

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

return singleobj
}

}

Ответ 7

Основываясь на ответном голосе: (и реквизит к нему!)

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

Вы уничтожаете объекты, а не классы. Нет ничего плохого в статических классах - С# предоставляет их по какой-то причине. Синглтоны - это дополнительные дополнительные накладные расходы, если только вам не нужен объект, например. когда вам нужно передать объект в качестве параметра.

Статические классы содержат только статические переменные. Эти переменные имеют тенденцию длиться в течение всего срока действия приложения, и в этом случае вам не нужно беспокоиться об утилизации ссылочных объектов, если у вас нет мягкого случая OCD. Это просто оставляет случай, когда ваш статический класс выделяет и освобождает ресурсы на протяжении всей своей жизни. Утилизируйте эти объекты со временем, как обычно (например, "используя..." ).

Ответ 9

Вы можете создать метод в статическом классе, который сбрасывает значения всех свойств. У вас есть статический класс

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

Теперь вы можете использовать любой из нижеперечисленных подходов из любого другого класса в значение reset статического класса

Подход 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

Вставлять объекты в статический класс при запуске из нестатического класса, который реализует 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);
    }

В моем конструкторе моей формы я вызываю следующее, чтобы настроить регистратор.

Logger.InitLogger(LogError);

Затем из любого класса в моем проекте я могу сделать следующее:

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