0

インスタンスクラスと静的クラスについて多くのことを読みましたが、私の質問に対する答えは見つかりませんでした。インスタンスクラスによって参照された静的クラスに別のクラスをインスタンス化することへの危険はありますか?

私が使用している現在の設計は、インスタンスクラスが静的な「ロガー」メソッド(一連のパラメーターを渡す)を呼び出して、ファイルシステム内のテキストファイルにエラーを記録する設計です。静的な「Logger」メソッドをリファクタリングして、パラメータークラス(一連のプロパティと、XMLまたは文字列としてそれ自体を返すいくつかのヘルパーメソッド)と、エラーをデータベースではなくデータベースに記録するDBLoggerクラスをインスタンス化します。ファイルシステム、唯一のパラメータとしてパラメータクラスを渡します。

このモデルは、静的ではなくLoggerクラスがインスタンス化されたレガシーVB6コードでうまく機能しました。

しかし、.NETコードでは、2つの新しいクラス(パラメーターとDBLogger)を静的にするか、DBLoggerを静的にしてパラメータークラスをインスタンス化するかがわかりません。静的クラスからインスタンスが作成されている(または作成されていない)場合の同時実行/マルチスレッドデータの問題の可能性について懸念しています。私は心配する権利がありますか、それとも何も心配していませんか?

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

// all code truncated for illustration purposes

namespace ThisIs.A.Test
{
    //INSTANCE
    public class ErrorLogParameters
    {
        private int mThreadId = 0;
        private int mErrorNumber = 0;
        private string mServerDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");

        public int ThreadId
        {
            get { return mThreadId; }
            set { mThreadId = value; }
        }
        public int ErrorNumber
        {
            get { return mErrorNumber; }
            set { mErrorNumber = value; }
        }
        public string ServerDate
        {
            get { return mServerDate; }
        }
    }

    //INSTANCE
    public class ErrorLog
    {
        public void LogErrorToDatabase(ErrorLogParameters criteria)
        {
            //Log error to database here
        }
    }

    //STATIC - Instantiates INSTANCE of ErrorLogParameters and ErrorLog
    public class Logger
    {
        public static void WriteLog(string pstrObjectName, string pstrProcedureName, int plngErrNumber, string pstrErrDescription)
        {
            // create a new parameter object
            ErrorLogParameters objParameters = new ErrorLogParameters();

            // populate object properties
            objParameters.ErrorNumber = mlngErrNumber;
            objParameters.ThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;

            ErrorLog objErrorLog = new ErrorLog();

            objErrorLog.LogErrorToDatabase(objParameters);
        }
    }

    //INSTANCE - Invokes STATIC method
    public class SomeInstance 
    {
        private void ErrorHandler_Log(Exception exception, string procedureName, string additonalDescription, string stackTrace)
        {
            // call from instance class to static class
            Logger.WriteLog(mstrObjectName, procedureName, mlngErrNumber, mstrErrDescription);
        }
    }

}
4

3 に答える 3

3

いいえ、それはまったく問題ありません。メソッド内で任意のクラスのインスタンスを作成する場合、そのメソッドを宣言するクラスが静的クラスであるかどうかは関係ありません。

さらに、何か「特別な」もの(たとえば、作成されたインスタンスの数をカウントする静的変数)がない限り、既存のオブジェクトを使用する場合よりも、新しいオブジェクトを作成するときに同時実行の問題が発生する可能性は低くなります。基本的に、ほとんどすべての並行性のトリッキーな部分は、可変データが共有される場所を解決することです-ここに何かがあるようには聞こえません(サンプルコードはそれを明確にするのに役立ちますが)。

于 2013-03-25T18:48:19.013 に答える
0

これには、プロバイダーとシングルトンパターンの組み合わせを使用します。

Loggerという抽象クラスを作成します。

  1. Loggerクラスには、ログに書き込むための抽象メソッドが含まれています。例えば:
    • 抽象voidLogInfo(LogInfo info);
    • 抽象voidLogError(例外例外);
  2. Loggerクラスには、Loggerオブジェクトのプライベートインスタンスが含まれています。
  3. Loggerクラスには、プライベートインスタンスを返す静的プロパティが含まれています。
  4. Loggerクラスには、Loggerオブジェクトのプライベートインスタンスをインスタンス化する静的コンストラクターが含まれています。おそらく、Reflectionを使用して、構成に基づいてオブジェクトをインスタンス化します。
  5. Loggerオブジェクトから継承するFileLoggerを実装します。このロガーはファイルに書き込みます。
  6. Loggerオブジェクトから継承するSQLLoggerを実装します。このロガーはデータベースに書き込みます。

次のようにロガーを呼び出します。

  • Logger.Instance.WriteInfo(info);
  • Logger.Instance.WriteError(例外);

この設計を使用することにはいくつかの利点があります。

  1. ロギング機能は完全に抽象化されています。これにより、ログの呼び出し元がログを書き込むコードから完全に切り離されます。これにより、任意のデータストアにログを書き込むことができます。
  2. コードをコンパイルせずに、使用するロガーを変更できます。設定ファイルを更新するだけです。
  3. シングルトンはスレッドセーフを保証します
  4. 妥当性。抽象クラスに対するモックテストを作成できます。

お役に立てれば。

于 2013-03-25T19:38:31.820 に答える
0

静的メソッドには並行性の問題はありません。

静的変数は別の問題です。

于 2013-10-03T01:40:37.070 に答える