避免“通过派生类型访问类型的静态成员”

时间:2010-12-10 05:28:06

标签: c# inheritance static static-methods

我认为这纯粹是一个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);
}

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

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

TIA!
詹姆斯

1 个答案:

答案 0 :(得分:5)

似乎你想要保持门的延伸,但不是为了修改,也就是开放封闭原则。这是一个有价值的目标。

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

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

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

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