Могу ли я сбросить статический / общий класс? - PullRequest
6 голосов
/ 04 мая 2009

У меня есть класс shared (static в C #), который в основном содержит некоторые данные настроек, которые любой класс в приложении может читать и иногда записывать. Также есть некоторые статические свойства, которые содержат некоторые внутренние состояния.

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

В одиночной модели я бы просто обновил ее примерно так:

Public Sub Reset() 
    _Instance = New MyClass()
End Sub

Однако это невозможно в классе Shared. Есть ли идеи о том, как я могу это сделать? Или я должен переключить обратно на Singleton?

Ответы [ 5 ]

8 голосов
/ 04 мая 2009

Нет способа сделать это так же, как модель, которую вы только что указали. Причина в том, что нет резервного хранилища данных для «сброса». Однако вы можете смоделировать это, используя явный метод для инициализации всех наших данных.

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
3 голосов
/ 04 мая 2009

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

Два варианта состоят в том, чтобы переключиться (назад) на синглтон.

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

1 голос
/ 04 мая 2009

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

0 голосов
/ 13 января 2018
  • быстрый подход с точки зрения времени выполнения - сброс значений с помощью метода, который сбрасывает каждое значение.

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

если ваш статический класс имеет специальные инициализированные свойства / поля, используйте метод для инициализации этих полей, т.е. первый подход.

если у вашего статического класса есть инициализированные свойства / поля null / default, используйте отражение, чтобы перебрать все элементы данных и вернуть им значение по умолчанию.

использование сочетания обоих подходов к кодированию экономит время и снижает вероятность появления ошибок.

Этот код сбрасывает все поля 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 и выполните тот же цикл для их сброса.

0 голосов
/ 18 ноября 2014

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

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