
先一针见血指出你的误区publicstaticpartialclassNtsHelper{privatestaticreadonlyGeometryFactory_factorynewGeometryFactory();privateconstdoubleTolerance1e-6;publicstaticdoubleGetTolerance(){returnTolerance;}}这里_factory、Tolerance根本就不是「非静态成员」它们两个全部都是静态成员。逐条拆解每个字段1.private static readonly GeometryFactory _factory修饰符static静态字段属于类NtsHelper不属于任何实例对象。readonly只是代表只能在构造阶段赋值一次之后不可修改readonly ≠ 实例成员很多人踩坑以为readonly 实例变量。static readonly→ 静态只读全局唯一readonly不带static→ 实例只读每个new出来的对象一份副本2.private const double Tolerance 1e-6;const常量天生就是隐式静态的哪怕你不写static编译器也会把它当成静态。常量永远属于类不属于对象实例。所以下面静态方法GetTolerance()直接 return Tolerance完全合法。3.GetTolerance()标记了static静态方法。静态方法只能直接访问本类的静态成员你这里刚好符合规则。对比两张对照表彻底分清✅ 你代码里全部静态//静态只读字段属于类privatestaticreadonlyGeometryFactory_factory;//常量天生隐式静态privateconstdoubleTolerance1e-6;//静态方法publicstaticdoubleGetTolerance(){}❌真正的非静态(实例)成员长这样没有staticpublicpartialclassNtsHelper{//实例字段必须 new NtsHelper() 创建对象之后才有privatereadonlyGeometryFactory_factory;privatedouble_myValue;//实例方法publicdoubleGetValue(){return_myValue;}}⚠️ 注意static class静态类禁止出现任何不带static的实例成员。如果你在静态类写publicstaticpartialclassNtsHelper{privatereadonlyGeometryFactory_factory;//编译报错}编译器直接红色报错静态类不能包含实例字段。回到你项目设计的优点管网NTS工具类privatestaticreadonlyGeometryFactory_factorynewGeometryFactory();_factory全局只实例化一次程序启动就创建好。所有地方调用NTS几何计算复用同一个GeometryFactory对象不用每次计算都new一个工厂节省内存、性能更好。快速记忆口诀static readonly静态只读一份全局副本。readonly实例只读每个对象一份。const天生隐式静态不需要写static。静态类里面所有成员必须带static编译器强制要求。核心结论先给你把3条功能责任分清全局唯一static的功劳只能构造阶段赋值一次 运行后不能修改readonly的功劳readonly确实是「只读」但不是编译期常量它是「运行时只读锁」。下面拆开逐个讲清楚。一、readonly到底是什么能干2件事功能1赋值时机受限字段只能在两个地方赋值声明的时候直接初始化public readonly double a 10;类的构造函数里面实例构造函数 / 静态构造函数构造执行完毕之后代码任何地方再也不能给这个字段赋值、修改它。功能2运行期间禁止改写构造跑完你写xxx 5;修改readonly字段编译器直接报错。⚠️ 非常重要的误区readonly本身完全不控制“全局唯一”。如果你只写readonly、不加static每new一个对象就会生成一份全新副本实例‑readonly不带static例子classDemo{//实例只读字段每new一个对象就有一份独立副本publicreadonlydoubleValue;publicDemo(doublev){Valuev;//✅构造函数内允许赋值}}vard1newDemo(10);vard2newDemo(20);//d1.Value 和 d2.Value 是两份完全独立的数据这里只有readonly没有static不是全局唯一二、static 干的是什么static的职责只有一件事这个字段属于【类本身】而不属于new出来的对象实例整个程序内永远只有1份副本全局唯一static完全不管你能不能修改publicstaticintCount0;Count100;//✅随便改static不锁读写static只管「几份副本」根本没有只读、不可修改的能力。三、static readonly组合就是你NtsHelper里面的写法privatestaticreadonlyGeometryFactory_factorynewGeometryFactory();两个关键字分工清晰各司其职static→全局唯一全程序只有这一个_factory对象不需要new实例就能访问readonly→赋值锁定只能初始化那一次后面代码禁止修改 _factory特性由哪个关键字提供全局唯一、一份副本static仅构造阶段可赋值一次readonly运行全程不能修改readonly分开对比static管「有几份」readonly管「能不能改、什么时候赋值」四、再把 const 拉进来对比你代码里还有const double Toleranceconst编译期常量天生隐式staticprivateconstdoubleTolerance1e-6;编译的时候值就被钉死不能在构造函数赋值天生全局唯一不能加readonly。一张终极对比总表写法副本数量(全局唯一?)什么时候能赋值运行时能否修改int x;实例每个new对象一份任何地方可读写readonly int x;实例每个new对象一份声明处 / 实例构造函数❌不可修改static int x;全局唯一1份任何地方✅随便读写static readonly int x;全局唯一1份声明处 / 静态构造函数❌不可修改const int x 1;全局唯一1份只能声明时赋值❌编译期固定不可修改五、结合你NTS管网代码解释privatestaticreadonlyGeometryFactory_factorynewGeometryFactory();staticGeometryFactory 工厂对象全局就创建1个所有管线几何运算共用它readonly写完之后代码不能再把_factory null或者_factory new GeometryFactory()防止运行时被意外覆盖引发难以排查的NTS崩溃。高频踩坑点❌误区readonly 全局唯一错不带static的readonly每个实例一份。❌误区static 不能修改错static变量默认完全可读写。❌误区static readonly和const完全等价不等价static readonly可以在静态构造函数里面动态赋值const只能写死字面量。