2010-12-10 157 views
2

我相信这纯粹是一个Resharper警告,但其背后的理由(解释为here)很合理。什么Greg Beech的意思是,你可以调用从同级类的基类的静态方法......在他的榜样,他用:避免“通过派生类型访问类型的静态成员”

var request = (FtpWebRequest)HttpWebRequest.Create(...) 

...这是一种误导。

那么有没有一种设计可以让我在下面的课程中避免这种警告?

public abstract class BaseLog { 

    // I omitted several other properties for clarity 
    protected static string category; 
    protected static TraceEventType severity; 

    static BaseLog() { 
     category = "General"; 
     severity = TraceEventType.Information; 
    } 

    public static void Write(string message) { 
     Write(message, category, severity); 
    } 

    // Writes to a log file... it's the same code for 
    // every derived class. Only the category and severity will change 
    protected static void Write(string message, string messageCategory, TraceEventType messageSeverity) { 

     LogEntry logEntry = new LogEntry(message, messageCategory, messageSeverity); 

     // This is Microsoft's static class for logging... I'm wrapping it to 
     // simplify how it's called, but the basic principle is the same: 
     // A static class to log messages 
     Logger.Write(logEntry); 

    } 

} 


public class ErrorLog : BaseLog { 

    static ErrorLog() { 
     category = "Errors"; 
     severity = TraceEventType.Error; 
    } 

    // I can add more functionality to the derived classes, but 
    // the basic logging functionality in the base doesn't change 
    public static void Write(Exception exc) { 
     Write(exc.Message); 
    } 

} 


// Code that could call this... 
catch (Exception exc) { 
    // This line gives me the warning 
    ErrorLog.Write("You did something bad"); 
    ErrorLog.Write(exc); 
} 

One ErrorLog服务于应用程序,其设置永不改变(还有一个TraceLog和一个ThreadLog)。我不想复制日志代码,因为它对每个派生类都是完全相同的......保持它在BaseLog中的工作完美。那么我如何设计这个我不违反这个设计原则呢?

这些类是静态的,因为我不想在每次我想记录某些东西时实例化一个新的对象ErrorLog,而且我不希望每个对象中有50个以每个成员级变量的形式浮动我写的课。日志记录使用微软的企业库,如果这有所作为。

TIA!
James

回答

5

看起来好像你想保持开放的扩展门,但不是修改又名开放闭合原则。它是一个有价值的目标。

我的建议是失去静态粘附 - 将函数保持器类转为对象。这允许您根据需要覆盖(而不是混淆其他读者) - 多态只能用于实例。

下一个问题是需要有一个全局对象vs传递一个记录器实例。 创建另一种类型,用于访问记录器对象的单个实例。 (旧的单身人士)

e.g. ErrorLogProvider.Instance.Write(something) 

PS:免费赠品 - 更容易测试这些对象。

+0

有趣的方法...今晚将围绕我的头。因此,如果我正确地跟踪了你,`ErrorLogProvider`将是一个静态类,其类型为`ErrorLog`,它将在提供者的静态构造函数中实例化并通过`Instance`属性暴露 – 2010-12-10 05:51:58