使用另一个类的c#静态类

本文关键字:静态类 另一个 | 更新日期: 2023-09-27 18:01:36

我有一个记录器API,我可以用它来记录文本。日志记录器有一些属性,我可以用来记录事件类型(Info, Err等…),源应用程序(app1, app2等…)和mesg文本。

语法简单,运行正常:

Logger log = new Logger();
log.Write("Information", "SourceApplication", "Test text to log");

现在我正在考虑创建2个静态类,一个用于"通用日志",另一个用于"调试日志"。目标是避免为每个模块的使用创建一个新的日志记录器对象实例。每个类都应该能够在没有实例化的情况下使用这些对象(静态类应该自动处理这个问题)。

"Debug Logging" -可以在解决方案中的任何项目中使用,并且应该是单例的。调用者代码应该是:

LoggerDebug.Write("Debug", "Debugger", "Test text to log");

通用日志记录-所有项目模块都可以使用,但是在每次使用之后,静态类应该释放Logger对象调用者代码应该是:

LoggerDebug.Write("Information", "App1", "Test text to log");

我试着从"调试日志"静态类开始,我读(http://csharpindepth.com/Articles/General/Singleton.aspx),但我不确定这是否是正确的方法…你能给我一些建议吗?

using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace Common
{
    public sealed class LoggerDebug
    {
        private static LoggerDebug instance = null;
        private static readonly object padlock = new object();
        private static Logger log;
        static LoggerDebug Instance
        {
            get
            {
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new LoggerDebug();
                    }
                    return instance;
                }
            }
        }
        public LoggerDebug()
        {
            log = new Logger();
        }
        public static void Write(String EventType, string appSource, string text)
        {
            log.Write(EventType, appSource, string.Format("Test {0}", text));
        }
    }
}

调用者代码如下所示:

LoggerDebug.Write("Information", "App1", "Test text to log");

当我尝试运行应用程序时,它崩溃了:

类型为"System"的未处理异常。得到NullReferenceException"附加信息:对象引用不存在设置为对象的实例。

表示该actor没有实例化log = new Logger();

所以我可以纠正这个问题:

private static Logger log = new Logger();

和注释函数代码

public LoggerDebug()
{
    //log = new Logger();
}

但是我很困惑,不确定这是否是正确的方法来做到这一点,如何正确地做到这一点?

有我可以用的例子吗?

使用另一个类的c#静态类

下面是更新后的代码。使整个东西是静态的,因为没有实例成员/方法。参见代码中的注释。

顺便说一句,我强烈建议你不要为了学习经验而这样做。使用现有的框架,如Log4Net或NLog,它们是高度可配置和广泛测试。

using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace Common
{
    // changed sealed to static as there are no instances
    public static class LoggerDebug
    {
        // removed lock object 
        private static Logger log;
        // added static constructor
        static LoggerDebug(){
            log = new Logger();
        }
        // no need for lock due to static constructor
        // removed Instance
        // removed instance constructor
        public static void Write(String EventType, string appSource, string text)
        {
            log.Write(EventType, appSource, string.Format("Test {0}", text));
        }
    }
}

或者你可以使用Singleton模式,但是你至少需要一个实例级(非静态)成员才能使用它。

using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace Common
{
    // changed sealed to static as there are no instances
    public sealed class LoggerDebug
    {
        // removed lock object 
        private static Logger log;
        // added static constructor
        static LoggerDebug(){
            log = new Logger();
            _logger = new LoggerDebug();
        }
        // singleton that is created only once
        private static LoggerDebug _logger;
        public static LoggerDebug Logger{
            get{return _logger;}
        }
        // removed static keyword
        public void Write(String EventType, string appSource, string text)
        {
            log.Write(EventType, appSource, string.Format("Test {0}", text));
        }
    }
}

您还可以像在示例中那样内联地初始化静态字段。理想情况下,您永远不希望在实例级成员中初始化静态字段,因为可能存在竞争条件,并且必须为每个实例编写执行检查的费用,这是不高效的,并且会导致代码脆弱。