C#私有、静态和只读

C#私有、静态和只读,c#,log4net,access-modifiers,C#,Log4net,Access Modifiers,我在查看log4net的一些代码时遇到了这个问题 private static readonly ILog logger = LogManager.GetLogger(typeof(AdminClient)); 我想知道为什么您需要私有静态只读 从我的理解来看,private意味着变量不能在类之外使用,除非存在访问器方法或get属性 静态意味着变量的作用域仅限于此文件 readonly意味着您只能读取该值,而不能分配该值 所以,我想写这段代码的人。声明为private,因为他们不希望在类外部使

我在查看log4net的一些代码时遇到了这个问题

private static readonly ILog logger = LogManager.GetLogger(typeof(AdminClient));
我想知道为什么您需要私有静态只读

从我的理解来看,private意味着变量不能在类之外使用,除非存在访问器方法或get属性

静态意味着变量的作用域仅限于此文件

readonly意味着您只能读取该值,而不能分配该值

所以,我想写这段代码的人。声明为private,因为他们不希望在类外部使用它,而声明为static,这样他们就不希望在文件外部使用它。但是,如果存在get静态属性,则会阻止这种情况发生

我想我可以理解只读,值只能从中读取,不能设置

非常感谢您的建议,

  • private任何人都不应在类外使用logger字段(即使在子类中),如果您不设置此字段,任何其他类都可以使用您的logger以您的类的名称进行日志记录
  • static属性附加到类,因此不会在类的每个实例中重复。如果不设置此属性,logger属性将在系统对对象创建的每个实例中占用额外的内存空间(您误解了这一点)
  • 只读不应修改记录器字段

static并不意味着不能从其他文件访问它-这不是C。static关键字意味着记录器对象是一个类变量而不是一个实例变量,因此即使从该类的不同对象访问,它们都将引用同一个记录器对象。

我认为您误解了static。静态并不意味着“不能在文件外使用”。静态意味着:每个类有一个。此声明所做的是创建一个只分配一次(静态)的记录器,该记录器仅在类中可用(在派生类中也不可用)(private),并且不能在初始化后写入(readonly)


好问题

static在c#中表示成员与类关联,而不是与类的实例关联。只读很重要,因为在c#中,大多数变量,尤其是这一个,都是引用变量。只读意味着此变量将始终引用同一个记录器。

Areadonly变量非常类似于const,因为该值在其整个生命周期内是恒定的。不同之处在于只读变量在运行时初始化,常量在编译时初始化Static,在某种外行术语中,意味着变量的实例不依赖于声明它的对象的实例。它的生命周期从一个函数调用持续到另一个函数调用。静态变量访问速度更快,因为它的存储在整个程序期间保持分配状态。知道了这一点,我们可以回到你的问题上来


为什么“记录器”是静态成员?这是一个设计决定。我需要知道你是如何用它来回答这个问题的。为什么它是只读的?因为它似乎只初始化了一次,并且它的实例在整个过程中都被使用。我们可以在初始化logger后立即将其设置为“只读”,以确保没有其他人篡改logger的值。

开发人员的意思是,当他们在此类的任何实例中调用logger.Info(…)时,他们希望使用公共(静态)实例(因此不需要为每个类实例创建新的logger),他们想确定它自创建以来没有改变(只读),如果我们在派生类的虚函数中,那么我想确保我没有错误地使用基类(private)

在私有变量上设置只读标志的原因是声明该变量将始终引用同一对象。 的确,私有化会使它对类外的任何人都不可见,但通过这种方式,我们可以确保不会意外地用新对象覆盖变量,比如

logger = LogManager.GetLogger(typeof(AdminClient));

在我们班的其他地方。使用readonly,它不会编译(除非之前没有初始化,我们在(静态)构造函数中)

静态变量属于“类变量”类别,类变量是与类而不是类对象关联的变量,另一方面,实例变量是与类对象关联的变量,这意味着每次初始化一个类对象时,该对象将有其自己的“实例变量”(非静态)副本,而在运行程序中,静态变量在类的所有对象之间共享,如链表的大小等。
readonly是用于使变量只读的c#关键字,java不提供这样的功能,您必须编写一个公共方法来访问您不想修改的变量。

对不起,我知道这已经得到了回答,而且非常旧,但我想让任何看到本文的人都知道,这就是您设置变量的方式“Singleton”模式。任何想进一步了解问题中代码示例的人都可能会从学习更多关于Singleton及其使用方法(中介器、记录器、异步回调等)中获益

//关于单身汉的母舰故事


//关于它们的一次伟大的讨论

关于这个特定模式的一个有趣的旁白:我曾经声明这是
受保护的静态只读
,这让我从VS代码分析中得到了一个“:不要声明只读可变引用类型”警告。如前所述,“一个
受保护的只读
字段并不是很清楚。由于
受保护
,您可能希望派生类可以初始化字段。“将声明更改为
私有静态只读
修复了此问题。