هل يمكنني إعادة تعيين فئة ثابتة/مشتركة؟
سؤال
لقد حصلت على 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;
}
}
النهج السريع من حيث وقت التنفيذ هو إعادة تعيين القيم باستخدام طريقة تعيد تعيين كل قيمة.
استخدم الانعكاس إذا كنت تريد توفير وقت البرمجة وكتابة كود خالٍ من الأخطاء.إذا كانت فئتك الثابتة تحتوي على العديد من الحقول الثابتة، فإن استخدام الانعكاس يقلل من فرصة فقدان خاصية أو حقل.
إذا كانت فئتك الثابتة تحتوي على خصائص/حقول خاصة تمت تهيئتها، فاستخدم طريقة لتهيئة تلك الحقول، أي النهج الأول.
إذا كانت فئتك الثابتة تحتوي على خصائص/حقول فارغة/افتراضية، فاستخدم الانعكاس للتكرار على جميع أعضاء البيانات وإعادة تعيينهم إلى القيمة الافتراضية.
استخدم مزيجًا من كلا الطريقتين للبرمجة لتوفير الوقت وتقليل احتمالية ظهور الأخطاء.
يقوم هذا الرمز بإعادة تعيين جميع حقول 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
كذلك وقم بنفس الحلقة لإعادة ضبطها.