繁体   English   中英

C#中的实例类->静态类->实例类

[英]instance class->static class->instance class in C#

我已经大量阅读了实例和静态类,但没有找到我的问题的答案。 在实例类引用的静态类中实例化其他类是否存在任何风险?

我正在使用的当前设计是其中实例类调用静态“ Logger”方法(传递一系列参数)以将错误记录到文件系统中的文本文件中的一种设计。 我正在重构静态的“ Logger”方法以实例化一个参数类(它只是一系列属性和一些帮助程序方法以XML或字符串形式返回自身)和一个DBLogger类来将错误记录到数据库而不是数据库中。文件系统,将参数类作为唯一的参数传递。

该模型在我的旧版VB6代码中运行良好,其中Logger类是实例化的,而不是静态的。

但是现在在.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);
        }
    }

}

不,那绝对很好-如果要在方法中创建任何类的实例,则声明该方法的类是否为静态类都没有关系。

此外,除非您有一些“特殊”的东西(例如,一个静态变量计算创建的实例数),否则与使用现有对象相比,创建对象时发生并发问题的可能性较小。 基本上,几乎所有并发中的棘手部分是确定共享可变数据的位置- 听起来好像没有什么在这里(尽管示例代码将有助于阐明这一点)。

我将为此使用提供程序和单例模式的组合。

创建一个称为Logger的抽象类。

  1. Logger类包含用于写入日志的抽象方法。 例如:
    • 抽象void LogInfo(LogInfo info);
    • 抽象void LogError(Exception exception);
    • 等等
  2. Logger类包含Logger对象的私有实例。
  3. Logger类包含一个返回私有实例的静态属性。
  4. Logger类包含一个静态构造函数,该构造函数实例化Logger对象的私有实例。 您可能会使用Reflection并根据配置实例化该对象。
  5. 实现一个从Logger对象继承的FileLogger。 该记录器将写入文件。
  6. 实现一个从Logger对象继承的SQLLogger。 该记录器将写入数据库。

像这样调用记录器:

  • Logger.Instance.WriteInfo(info);
  • Logger.Instance.WriteError(exception);

使用此设计有一些优点:

  1. 您的日志记录功能已完全抽象。 这将日志记录调用程序与编写日志的代码完全分离。 这使您可以将日志写入任何数据存储。
  2. 您可以更改要使用的记录器,而无需编译代码。 只需更新配置文件。
  3. Singleton保证线程安全
  4. 可测试性。 您可以针对抽象类编写Mock测试。

希望这可以帮助。

静态方法没有并发问题。

静态变量是另一回事。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM