c#使用另一个类

时间:2016-08-10 12:31:07

标签: c# logging exception-handling

我有一个记录器API,可用于记录文本。 记录器有一些属性,我可以用来记录envent类型(Info,Err等...),源app(app1,app2等等)和mesg文本。

语法很简单,工作正常:

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

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

"调试记录" - 可以由解决方案内的任何项目使用,并且应该是单例。 要使用的来电码应为:

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

通用日志记录 - 供所有项目模块使用但在每次使用后,静态类应该处理Logger对象 要使用的来电码应为:

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

我试着从" Debug Logging"开始静态类,我读(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'   发生在Common.dll中附加信息:对象引用不是   设置为对象的实例。

那说ctor没有实例化log = new Logger();

所以我可以用以下方法解决这个问题:

private static Logger log = new Logger();

评论ctor代码

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

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

我可以使用的任何例子吗?

1 个答案:

答案 0 :(得分:1)

这是更新的代码。由于没有实例成员/方法,因此将整个事物设置为静态。请参阅代码中的注释。

另一方面,我强烈建议您不要为学习经历以外的任何事情做这件事。使用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));
        }
    }
}

您也可以像在示例中一样初始化静态字段。理想情况下,您永远不会想要在实例级别成员中初始化静态字段,因为可能存在竞争条件以及必须编写为每个实例执行的检查的费用,这样做效率很低并且会导致代码变弱。