一起谈.NET技术,关于c#静态方法和实例方法的辨析和应用

简介:   本文将围绕c#静态方法和实例方法讨论一下。针对一些观点,如:"静态方法是常驻内存", 还有"静态方法比实例方法先装载",做一个辨析。同时讨论下何时用静态方法,何时用实例方法。  前几日,在微软的好友发给我一个链接:《静态方法和实例化方法之间的区别你知道了嘛? 欢迎讨论!! - 问题最终 ...》,然后说这里某些观点需要澄清一下,希望我写一篇blog。

  本文将围绕c#静态方法和实例方法讨论一下。针对一些观点,如:"静态方法是常驻内存", 还有"静态方法比实例方法先装载",做一个辨析。同时讨论下何时用静态方法,何时用实例方法。

  前几日,在微软的好友发给我一个链接:《静态方法和实例化方法之间的区别你知道了嘛? 欢迎讨论!! - 问题最终 ...》,然后说这里某些观点需要澄清一下,希望我写一篇blog。我当时读了这篇blog. 文比较短,列举了静态方法和实例方法的几种案例,也没有论点,然后就请大家讨论。后面评论就比blog热闹多了。言辞也激烈,后来该blog作者干脆把这篇blog删了。现在已经看不到这篇blog了。现在我写这篇blog,一是针对一些观点做个辨析,二是完成好友的所托。

  c#静态方法和实例方法的几种用法,见如下代码:这三种形式我们应该都用过。

 
 
public class SomeClass
{
private string myfield = null ;
public static instance = new SomeClass();
public instranceMethod() {};
public static staticMethod() {};
}

public class AnotherClass
{
public static Main()
{
// 第一种方式, 声明实例,调用实例方法
SomeClass someClass = new SomeClass();
someClass.instanceMethod();

// 第二种方式,通过一个静态的实例,去调用实例方法
SomeClass.instance.instanceMethod();

// 第三种方式,直接调用静态方法
SomeClass.staticMethod();
}
}

  这几种方式在调用时间,还有线程安全,面向对象的编程方面都有差别。后文会谈到。

  "静态方法是常驻内存"

  这是那位blog作者在评论中给出的观点。我觉得"静态方法是常驻内存"的说法是不对的。要知道一个.net类型的静态方法是属于这个.net类型的。而这个.net类型是一个.net 程序集的一部分。这个.net程序集是被一个AppDomain装入到内存里面来的。这个AppDomain是可以从内存卸载的。一个有.net CLR的进程里面可以有多于一个的AppDomain,第一个AppDomain之后的AppDomain都可以动态创建和卸载。这些AppDomain中的.net程序集,既可以有静态方法,也可以有实例方法。不管是静态方法还是实例方法,都是随其程序集所在的AppDomain一起创建和卸载。第一个AppDomain在整个程序运行结束时也会最后被卸载。其中所含的.net程序集自然也卸载。看图1会更明白点。所以静态方法不存在常驻内存一说。

  "静态方法比实例方法先装载"

  这也是那篇blog的评论中某些人提出的观点。我不知道他们的论据是什么,但是我已经做过实验,而且也写过这两篇blog关于.net反射和metadata加载--致Jeffray Zhao等几位和firelong[继续讨论]关于Windows PE和.net assembly的加载来证明.net程序集的加载方式是整个地加载,而不是用到某个metadata才加载该metadata, 用到某个方法才加载该方法。因为静态方法和实例方法同属于一个.net类型,而一个.net类型属于一个.net程序集。在整个地加载一个.net程序集的时候,不管是静态方法还是实例方法,都随该程序集全部加载进内存。所以"静态方法比实例方法先装载"也是不成立的。

  何时用静态方法,何时用实例方法。

  先说实例方法,当你给一个类写一个方法,如果该方法需要访问某个实例的成员变量时,那么就将该方法定义成实例方法。一类的实例通常有一些成员变量,其中含有该实例的状态信息。而该方法需要改变这些状态。那么该方法需要声明成实例方法。

  静态方法正好相反,它不需要访问某个实例的成员变量,它不需要去改变某个实例的状态。我们把该方法定义成静态方法。

  第一种方式,声明实例,调用实例方法。

  当一个类有多个实例,例如学生这个类,实例可以有学生甲,学生乙,学生丙,等等,我们就用第一种方式。在多线程的情况下,只要每个线程都创建自己的实例,那么第一种方法通常是线程安全的。

  第二种方式,通过一个静态的实例,去调用实例方法。

  这种情况比较特殊,通常是整个程序里该类唯一的一个实例,我们通过调用该实例的实例方法来改变该实例的某些状态。这一个实例在多线程的情况下,通常是线程不安全的。除非我们给这个实例加锁。防止其他线程访问该实例。

  第三种方式,直接调用静态方法。

  这种情况下静态方法不需要去改变某个实例的状态。只要得到少量的参数就可完成既定事情。比如判断一个文件是否存在,只要给个文件路径和文件名,就能知道该文件是否存在。

  学识有限,敬请您指教。

目录
相关文章
|
14天前
|
开发框架 搜索推荐 算法
一个包含了 50+ C#/.NET编程技巧实战练习教程
一个包含了 50+ C#/.NET编程技巧实战练习教程
67 18
|
14天前
|
缓存 算法 安全
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
47 12
|
13天前
|
开发框架 人工智能 .NET
C#/.NET/.NET Core拾遗补漏合集(24年12月更新)
C#/.NET/.NET Core拾遗补漏合集(24年12月更新)
|
13天前
|
开发框架 算法 .NET
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
|
13天前
|
开发框架 Cloud Native .NET
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
|
15天前
|
程序员 C# 数据库
C# 比较对象新思路,利用反射技术打造更灵活的比较工具
中途接手的项目,碰到需要在更新对象信息时比较并记录差异的需求,最变态的还有附加要求,怎么办?有没有既能满足需求又能对项目影响最小的方法呢?分享这个我封装的方法,一个利用反射技术打造的更灵活的比较工具
|
27天前
|
开发框架 监控 .NET
C#进阶-ASP.NET WebForms调用ASMX的WebService接口
通过本文的介绍,希望您能深入理解并掌握ASP.NET WebForms中调用ASMX WebService接口的方法和技巧,并在实际项目中灵活运用这些技术,提高开发效率和应用性能。
41 5
|
1月前
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
107 13
|
2月前
|
存储 安全 物联网
C# 在物联网 (IoT) 应用中的应用
本文介绍了C#在物联网(IoT)应用中的应用,涵盖基础概念、优势、常见问题及其解决方法。重点讨论了网络通信、数据处理和安全问题,并提供了相应的代码示例,旨在帮助开发者更好地利用C#进行IoT开发。
101 3
|
2月前
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
49 4