質問

私は持っています shared クラス (static これは主に、アプリケーション内のどのクラスでも読み取り、場合によっては書き込みできるいくつかの設定データを保持します。また、内部状態を保持する静的プロパティもいくつかあります。

このクラスを初期段階に戻したいと思います。すべてのデフォルト変数などを使用します。 ユーザーが現在の状態をリセットして、アプリケーションを再起動せずに最初からやり直すことを希望しているとします。

シングルトン モデルでは、次のようなもので単純に更新します。

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

他のヒント

静的クラスのインスタンスがないため、これを静的クラスで行うことはできません。

2つのオプションは、シングルトンに切り替える(戻る)ことです。

別の方法として、クラスの各静的メンバーをリセットするメソッドがあります。

たぶん、呼び出されると、すべての変数をデフォルトにリセットする静的メソッドです。

すべてのプロパティの値をリセットする静的クラスでメソッドを作成できます。 静的クラスがあると考えてください

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/デフォルトで初期化されたプロパティ/フィールドがある場合は、リフレクションを使用してすべてのデータ メンバーを反復処理し、それらをデフォルト値にリセットします。

コーディングに両方のアプローチを組み合わせて使用​​すると、時間を節約し、バグが発生する可能性を減らします。

このコードは、次のすべてのフィールドをリセットします。 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 同様に、同じループを実行してそれらをリセットします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top