一起谈.NET技术,.NET Framework源码研究系列之---万法归宗Object

简介:   经过前面三篇关于.NET Framework源码研究系列的随笔,相信大家都发现其实.NET Framework的实现其实并不复杂,也许跟我们自己做的项目开发差不多。本人也是这样的看法。不过,经过仔细深入的研究,我们还是会发现一下平时很难注意到的东西,而这些东西对我们完善思路,开阔眼界,锻炼良好的编码素质有着很大的意义.  我们知道.NET中所有的类型(包括:引用类型,值类型)都从Object类派生过来,由此可以说Object是所有类型的根本。

  经过前面三篇关于.NET Framework源码研究系列的随笔,相信大家都发现其实.NET Framework的实现其实并不复杂,也许跟我们自己做的项目开发差不多。本人也是这样的看法。不过,经过仔细深入的研究,我们还是会发现一下平时很难注意到的东西,而这些东西对我们完善思路,开阔眼界,锻炼良好的编码素质有着很大的意义.

  我们知道.NET中所有的类型(包括:引用类型,值类型)都从Object类派生过来,由此可以说Object是所有类型的根本。那么今天我们就研究.NET(C#)中一切元素的根本---System.Object。

  Object类在.NET源码中的实现很简单,一共不过100行左右的代码,这也是我们有精力可以仔细研究它的每一行代码。先看它的定义.

 
 
1  [Serializable()]
2  [ClassInterface(ClassInterfaceType.AutoDual)]
3  [System.Runtime.InteropServices.ComVisible(true)]
4   public class Object

  由定义来看,Object好像是一个普通的类(莫非Object也从Object派生而来?! ^_^ )。Serializable标签说明了Object可以做序列化反序列化操作。

  ClassInterface(ClassInterfaceType.AutoDual),System.Runtime.InteropServices.ComVisible(true)是.NET为了支持COM特别设计的。除非你要手动包装COM,否则对于绝大部分时间都是用托管代码而言的人没什么意义。

 
 
1  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
2   public Object(){ }
3  [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
4  ~Object() {}

  从上面的代码看到Object只有一个空方法体的构造函数,这就是宇宙起源一样,刚开始什么都没有。此处要特别说明的是ReliabilityContract标签。ReliabilityContract定义某些代码的作者和依赖于这些代码的开发人员之间的可协靠性定。这是官方的定义,听起来有些玄乎。ReliabilityContract有两个属性,分别是两个枚举:Cer和ConsistencyGuarantee.Cer指在受约束的执行区域内调用时指定方法的行为;ConsistencyGuarantee指可靠性协定。看MSDN对这两个枚举的说明后,我们发现 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]为Object提供了安全性保证,就是说我们在调用Object构造函数时不管有没有遇到异常情况,总会获知执行结果。

  另外,Object显式定义了析构函数(又是一个不推荐的做法,好像微软很喜欢做的不推荐我们做@_@||),让我们能够手动释放对象占用的资源而不需要等到GC自动释放。

  要特别说明的是,这里有个我们很少遇到的一个概念:CER,即受约束的执行区域,是创作可靠托管代码的机制的一部分。CER 定义一个区域,在该区域中公共语言运行库 (CLR) 会受到约束,不能引发可使区域中的代码无法完全执行的带外异常。在该区域中,用户代码受到约束,不能执行会导致引发带外异常的代码。

  看完构造函数后我们看下Object中最常用的三个方法的实现,代码如下:  

 
 
public virtual String ToString(){
return GetType().ToString();
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Type GetType();
public virtual bool Equals(Object obj){
return InternalEquals(this, obj);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool InternalEquals(Object objA, Object objB);
public virtual int GetHashCode(){
return InternalGetHashCode(this);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int InternalGetHashCode(Object obj);

  感觉有的悲剧,因为这三个方法什么都没做,直接调用了CLR的内部方法,看来Object也是个马甲:( 。微软官方号称Object类是所有类的基类在此恐怕要打个问号。我猜想此Object非彼Object。说不定CLR中也有一个Object。

  如果说上面三个方法有点让人无语,那么下面的代码就更让人困惑了。

 
 
private void FieldSetter(String typeName, String fieldName, Object val){
  FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
   if (fldInfo.IsInitOnly)
     throw new FieldAccessException(Environment.
      GetResourceString("FieldAccess_InitOnly"));
  System.Runtime.Remoting.Messaging.Message.CoerceArg(val,
    fldInfo.FieldType);
  fldInfo.SetValue(this, val);
}
private void FieldGetter(String typeName, String fieldName, ref Object val){
  FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
  val = fldInfo.GetValue(this);
}
private FieldInfo GetFieldInfo(String typeName, String fieldName){
  Type t = GetType();
   while ( null != t){
    if (t.FullName.Equals(typeName)){
      break;
    }
    t = t.BaseType;
  }
   if ( null == t){
     throw new RemotingException(String.Format(CultureInfo.CurrentCulture,
    Environment.GetResourceString("Remoting_BadType"),typeName));
  }
  FieldInfo fldInfo = t.GetField(fieldName, BindingFlags.Public
    |BindingFlags.Instance |BindingFlags.IgnoreCase);
   if ( null == fldInfo){
     throw new RemotingException(String.Format(CultureInfo.CurrentCulture,
    Environment.GetResourceString("Remoting_BadField"),
      fieldName, typeName));
  }
   return fldInfo;
}    

  上面一段代码似乎读取或设置一个字段的值(我们也是这样的做法)。问题时,我根本没有找到Object中用到这几个方法的地方,private又决定了扩展类也不可能访问。那么这三个方法到底有什么用,恐怕只有微软自己知道了。

  小结

  经过上面的分析,我们发现Object实现其实很简单,几乎没有内容。但Object中出现的CER给我们撰写高安全性代码带来一点思考。

目录
相关文章
|
1月前
使用的是.NET Framework 4.0,并且需要使用SMTP协议发送电子邮件
使用的是.NET Framework 4.0,并且需要使用SMTP协议发送电子邮件
36 1
|
15天前
|
开发框架 缓存 监控
NET Framework 到 .NET 5/6 的迁移是重大的升级
本文详细介绍了从 .NET Framework 4.8 迁移到 .NET 5/6 的过程,通过具体案例分析了迁移策略与最佳实践,包括技术栈评估、代码迁移、依赖项更新及数据库访问层的调整,强调了分阶段迁移、保持代码可维护性及性能监控的重要性。
38 3
|
23天前
|
机器学习/深度学习 编解码 算法
【小样本图像分割-4】nnU-Net: Self-adapting Framework for U-Net-Based Medical Image Segmentation
《nnU-Net: 自适应框架用于基于U-Net的医学图像分割》是一篇2018年的论文,发表在Nature上。该研究提出了一种自适应的医学图像分割框架nnU-Net,能够自动调整模型的超参数以适应不同的数据集。通过2D和3D U-Net及级联U-Net的组合,nnU-Net在10个医学分割数据集上取得了卓越的性能,无需手动调整。该方法强调数据增强、预处理和训练策略等技巧,为医学图像分割提供了一个强大的解决方案。
53 0
【小样本图像分割-4】nnU-Net: Self-adapting Framework for U-Net-Based Medical Image Segmentation
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
本文讨论了在基于.NET 6和.NET Framework的WinForms项目中添加图表控件的不同方法。由于.NET 6的WinForms项目默认不包含Chart控件,可以通过NuGet包管理器安装如ScottPlot等图表插件。而对于基于.NET Framework的WinForms项目,Chart控件是默认存在的,也可以通过NuGet安装额外的图表插件,例如LiveCharts。文中提供了通过NuGet添加图表控件的步骤和截图说明。
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
|
3月前
|
开发框架 缓存 前端开发
实战.NET Framework 迁移到 .NET 5/6
从.NET Framework 迁移到.NET 5/6 是一次重要的技术革新,涵盖开发环境与应用架构的全面升级。本文通过具体案例详细解析迁移流程,包括评估现有应用、利用.NET Portability Analyzer 工具识别可移植代码、创建新项目、逐步迁移代码及处理依赖项更新等关键步骤。特别关注命名空间调整、JSON 序列化工具更换及数据库访问层重构等内容,旨在帮助开发者掌握最佳实践,确保迁移过程平稳高效,同时提升应用性能与可维护性。
106 2
|
3月前
|
开发框架 JSON 监控
实战指南:从 .NET Framework 迁移到 .NET 5/6 的策略与最佳实践
【8月更文挑战第28天】从 .NET Framework 迁移到 .NET 5/6 是一次重要的技术升级,涉及开发环境与应用架构的改进。本文通过具体案例分析,介绍迁移策略与最佳实践,帮助开发者顺利完成转变。
68 1
|
3月前
|
JavaScript 前端开发 开发者
Vue.js 响应式变革来袭!结合热点技术,探索从 Object.defineProperty 到 Proxy 的奇妙之旅,触动你的心
【8月更文挑战第30天】在 Vue.js 中,响应式系统自动追踪并更新数据变化,极大提升了开发体验。早期通过 `Object.defineProperty` 实现,但存在对新旧属性处理及数组操作的局限。Vue 3.0 引入了 `Proxy`,克服了上述限制,提供了更强大的功能和更好的性能。实践中,可根据项目需求选择合适的技术方案,并优化数据操作,利用懒加载等方式提升性能。
41 0
|
1月前
|
Java
Java Object 类详解
在 Java 中,`Object` 类是所有类的根类,每个 Java 类都直接或间接继承自 `Object`。作为所有类的超类,`Object` 定义了若干基本方法,如 `equals`、`hashCode`、`toString` 等,这些方法在所有对象中均可使用。通过重写这些方法,可以实现基于内容的比较、生成有意义的字符串表示以及确保哈希码的一致性。此外,`Object` 还提供了 `clone`、`getClass`、`notify`、`notifyAll` 和 `wait` 等方法,支持对象克隆、反射机制及线程同步。理解和重写这些方法有助于提升 Java 代码的可读性和可维护性。
|
3月前
|
Java
【Java基础面试二十】、介绍一下Object类中的方法
这篇文章介绍了Java中Object类的常用方法,包括`getClass()`、`equals()`、`hashCode()`、`toString()`、`wait()`、`notify()`、`notifyAll()`和`clone()`,并提到了不推荐使用的`finalize()`方法。
【Java基础面试二十】、介绍一下Object类中的方法
|
2月前
|
Python
类与面向对象编程(Object-Oriented Programming, OOP)
类与面向对象编程(Object-Oriented Programming, OOP)