Могу ли я сбросить статический / общий класс?
Вопрос
У меня есть shared
класс (static
в C #), который в основном содержит некоторые данные настроек, которые любой класс в приложении может прочитать, а иногда и записать.Также есть некоторые статические свойства, которые содержат некоторые внутренние состояния.
Теперь я хочу вернуть этот класс к начальной его стадии.Со всеми переменными по умолчанию и т.д. Предположим, что пользователь хочет сбросить текущее состояние и начать все сначала, не перезапуская приложение.
В одноэлементной модели я бы просто обновил ее чем-то вроде этого :
Public Sub Reset()
_Instance = New MyClass()
End Sub
Однако это невозможно в Shared
класс.Есть ли какие-нибудь идеи о том, как я могу этого добиться?Или мне следует переключиться Назад в Синглтон?
Решение
Нет способа сделать это так же, как только что указанная вами модель синглтона. Причина в том, что отсутствует хранилище данных для «сброса». Однако вы можете смоделировать это, используя явный метод для инициализации всех наших данных. Р>
Public Module MyClass
Public Sub Reset()
Field1 = 42
Field2 = "foo"
End Sub
Public Shared Field1 As Integer
Public Shared Field2 As String
End Module
Версия с классом против модуля
Public Class MyClass
Shared Sub New()
Reset
End Sub
Private Sub New()
' Prevent instantiation of the class
End Sub
Public Sub Reset()
Field1 = 42
Field2 = "foo"
End Sub
Public Shared Field1 As Integer
Public Shared Field2 As String
End 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="";
}
}
Теперь вы можете использовать любой из приведенных ниже подходов из любого другого класса для сброса значения статического класса
Подход 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;
}
}
быстрый подход с точки зрения времени выполнения заключается в сбросе значений с использованием метода, который сбрасывает каждое значение.
используйте отражение, если вы хотите сэкономить время на кодирование и написать код без ошибок.если ваш статический класс содержит много статических полей, использование отражения снижает вероятность отсутствия свойства или поля.
если ваш статический класс имеет специальные инициализированные свойства / поля, используйте метод для инициализации этих полей, то есть первый подход.
если ваш статический класс имеет инициализированные свойства / поля null / default, используйте reflection для перебора всех элементов данных и сброса их к значению по умолчанию.
использование сочетания обоих подходов к кодированию экономит время и снижает вероятность появления ошибок.
Этот код сбрасывает все поля MyStaticClass
.затем вызывает метод Init, чтобы инициализировать меньшее количество остальных полей.
var fields = typeof(MyStaticClass).GetFields(BindingFlags.Static | BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Public);
foreach (var field in fields)
{
var type = field.GetType();
field.SetValue(null, null);
}
Init(); // if there are values to be initialized
если ваш статический класс имеет свойства, вызовите GetProperties
также проделайте тот же цикл, чтобы сбросить их.