Как уничтожить статический класс в С#
Я использую .net 1.1. У меня есть класс сеанса, в котором я сохранил много статических переменных, которые содержат некоторые данные, которые будут использоваться многими классами.
Я хочу найти простой способ уничтожить этот класс вместо того, чтобы каждый раз переустанавливать каждую переменную. Например, если есть статический класс MyStatic, мне бы хотелось уничтожить/удалить этот класс из памяти, написав MyStatic = null, что в настоящее время невозможно,
Дополнительный вопрос.
Идея singleton хороша, но у меня есть следующие вопросы:
Если реализован синглтон, в памяти останется еще один объект. В singleton мы проверяем только если экземпляр уже существует. как я могу убедиться, что эта переменная экземпляра также будет уничтожена.
У меня есть основной класс, который инициализирует переменную в статическом классе. Даже если я планирую реализовать метод Rest(), мне нужно вызвать его из метода, например деструктора в основном классе. Но этот деструктор вызывается только тогда, когда GC собирает этот основной объект класса в памяти, что означает, что Reset() вызывается очень поздно
спасибо
Прадип
Ответы
Ответ 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);