我想要完成的是:

Logger类应将LogMedia的集合声明为成员变量,并且只需要声明一个函数:void LogException( Exception ex )。在此函数内部,应循环浏览所有LogMedia实例,并调用每个实例中定义的虚函数。

我无法理解的是如何实现遍历所有这些实例的循环。或者,也许我应该如何创建这些实例?

记录仪类别

public class Logger
    {
       static List<LogMedia> m_loggers = new List<LogMedia>();

         **//Should I create som instances here?**
        public static void LogException(Exception ex)
        {
            foreach(var i in m_loggers)
            {
                i.LogMessage(ex.Message + Environment.NewLine);
            }
        }

        }
    }


LogMediaClass *:然后,我要创建类logmedia和其他三个类,其中“每个派生类随后应在LogMedia类中重写此函数。如何创建这三个类的实例,以便可以遍历它们,如图所示在记录仪中?*

public class LogMedia
    {
        public virtual void LogMessage(string Message) { } //virtual function that doesen't do anything

    }
    public class OutputWindowLogMedia : LogMedia
    {
        public override void LogMessage(string Message)
        {
            System.Diagnostics.Debug.WriteLine(Message);
        }
    }
    class TextFileLogMedia : LogMedia
    {
        public override void LogMessage(string Message)
        {
            StreamWriter writer = new StreamWriter("C:\\Temp\\xxx\\xxxx.txt");
            writer.WriteLine(Message + " the error occured at: ");
            writer.Close();
        }
    }
    class EmailLogMedia : LogMedia
    {
        public override void LogMessage(string Message)
        {


            const string senderID = "[email protected]"; // use sender's email id here..
            const string toAddress = "[email protected]";
            const string senderPassword = "xxxx"; // sender password here...
            try
            {
                SmtpClient smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com", // smtp server address here...
                    Port = 587,
                    EnableSsl = true,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    Credentials = new System.Net.NetworkCredential(senderID, senderPassword),
                    Timeout = 30000,
                };
                MailMessage message = new MailMessage(senderID, toAddress, "erroe", "error");
                smtp.Send(message);
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Error sending mail:" + ex.Message);
                Console.ResetColor();
            }

        }
    }

最佳答案

请在静态构造函数中初始化。

在其中添加所有记录器。可以确保每当调用LogException()时,都会看到该列表是静态的,从而填充列表。

只是侧面考虑,一定要将基本LogMedia设置为abstract或最好是interface

现在也有一个副作用,每当将来某个时候添加新的LogMedia时,必须在静态构造函数中添加Add调用。

这可能会导致大型项目出现维护错误,因此,为避免这种情况,请在静态构造函数中添加InitializeAllLoggers()方法,并将以下代码放入其中。

foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies().ToList())
{
    foreach (Type classType in assembly.GetTypes())
    {
         if (classType.IsClass
                    && !classType.IsAbstract
                    && classType.IsSubclassOf(typeof(LogMedia)))
         {
              m_loggers.Add(Activator.CreateInstance(classType) as LogMedia);
         }
    }
}


这样可以确保每当创建新的LogMedia类型时,它都会自动添加到记录器列表中。

10-07 20:18