¿Puedo restablecer una clase estática / compartida?
Pregunta
Tengo una clase compartida
( static
en C #) que en su mayoría incluye algunos datos de configuración que cualquier clase en la aplicación puede leer y, a veces, escribir. También hay algunas propiedades estáticas que mantienen algunos estados internos.
Ahora quiero revertir esta clase a la etapa inicial de la misma. Con todas las variables predeterminadas, etc. Suponga que el usuario desea restablecer el estado actual y comenzar de nuevo sin reiniciar la aplicación.
En un modelo de singleton simplemente lo renovaría con algo como esto:
Public Sub Reset()
_Instance = New MyClass()
End Sub
Sin embargo, esto no es posible en una clase Shared
. ¿Hay alguna idea acerca de cómo puedo lograr esto? ¿O debería cambiar de nuevo a Singleton?
Solución
No hay forma de hacerlo de la misma manera que el modelo Singleton que acaba de señalar. La razón es que no hay un almacén de datos de respaldo para " restablecer " ;. Sin embargo, lo que podría hacer es simular esto utilizando un método explícito para inicializar todos nuestros datos.
Public Module MyClass
Public Sub Reset()
Field1 = 42
Field2 = "foo"
End Sub
Public Shared Field1 As Integer
Public Shared Field2 As String
End Module
Versión con una clase frente a un módulo
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
Otros consejos
No puedes hacer esto en una clase estática, ya que no hay una instancia de una clase estática.
Las dos opciones serían cambiar (volver) a un singleton.
Alternativamente, podrías tener un método que reinicie a cada uno de los miembros estáticos de la clase.
Tal vez un método estático que cuando se llama, restablece todas las variables a sus valores predeterminados.
Puedes crear un método en la clase estática que restablece los valores de todas las propiedades. Considera que tienes una clase estática
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="";
}
}
Ahora puede usar cualquiera de los siguientes enfoques de cualquier otra clase para restablecer el valor de una clase estática
Enfoque 1: llamar directamente
ClassA.ResetValues();
Enfoque 2: invocar el método de forma dinámica desde un espacio de nombres conocido y una clase conocida
Type t1 = Type.GetType("Namespace1.ClassA");
MethodInfo methodInfo1 = t1.GetMethod("ResetValues");
if (methodInfo1 != null)
{
object result = null;
result = methodInfo1.Invoke(null, null);
}
Enfoque 3: invocar el método dinámicamente desde un conjunto / conjunto de conjuntos
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;
}
}
-
el enfoque rápido en términos de tiempo de ejecución es restablecer los valores mediante un método que restablece cada valor.
-
use reflexión si desea ahorrar tiempo de codificación y escribir un código libre de errores. Si su clase estática tiene muchos campos estáticos, el uso de la reflexión reduce la posibilidad de perder una propiedad o campo.
si su clase estática tiene propiedades / campos inicializados especiales, use un método para inicializar esos campos, es decir, el primer enfoque.
si su clase estática tiene propiedades / campos inicializados nulos / predeterminados, use la reflexión para iterar sobre todos los miembros de datos y restablecerlos al valor predeterminado.
utilice la combinación de ambos enfoques para codificar el ahorro de tiempo y reducir el potencial de introducción de errores.
Este código restablece todos los campos de MyStaticClass
. luego llama al método Init para inicializar menos resto de campos.
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
Si su clase estática tiene propiedades, llame también a GetProperties
y haga el mismo ciclo para restablecerlas.