【问题标题】:Avoiding "Access to a static member of a type via a derived type"避免“通过派生类型访问类型的静态成员”
【发布时间】:2010-12-10 05:28:05
【问题描述】:

我相信这纯粹是一个 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!
詹姆斯

【问题讨论】:

    标签: c# inheritance static static-methods


    【解决方案1】:

    您似乎想保持门打开以进行扩展,而不是进行修改,即打开关闭原则。这是一个有价值的目标。

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

    下一个问题是需要一个全局对象而不是传递一个记录器实例。 创建另一种类型以提供对记录器对象的单个实例的访问权限。 (老单身)

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

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

    【讨论】:

    • 有趣的方法...今晚我将围绕这个问题展开讨论。所以,如果我没听错的话,ErrorLogProvider 将是一个静态类,其静态成员变量类型为ErrorLog,它将在提供者的静态构造函数中实例化并通过Instance 属性公开
    • @James - 是的。 ErrorLogProvider 负责提供对(缓存的?)记录器对象的访问。此方法的返回类型可以是基本类型 - 允许客户端不关心记录器的确切类型。 ErrorLogProvider 可以根据配置文件/DI/显式初始化方法设置正确类型的记录器...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 2021-12-05
    • 2017-11-27
    相关资源
    最近更新 更多