一.所有类型都是从System.Obejct派生

1.下面两个类型定义是完全一致的:

 class Employee{
...
}
class Employee:System.Object{
...
}

2.System.Object的公共实例方法

  a.Equals 判断对象是否具有相等的值

  b.GetHashCode 返回对象值的哈希码

  c.ToString 该方法默认返回类型的完整名称( this.GetType().FullName )

  d.GetType 返回从Type派生的一个对象的实例,指出调用GetType的那个对象是什么类型

3.System.Object的受保护方法

  a.MemberwiseClone 这个非虚方法能创建类型的新实例,并将新对象的实例字段设与this对象的实例字段完全一致.返回的是一个对新实例的引用( 这是译文,说实话,没看懂,然后查阅了MSDN,其实这个方法的功能是创建一个浅表副本,是创建一个新对象,然后将当前对象的非静态字段复制到这个浅表副本中,即新对象中.如果字段是值类型,则执行逐位复制.如果是引用类型,则复制引用而不复制引用对象,因此,原始对象及其副本引用同一对象 )

  以下是浅表复制和深入复制操作的区别

     public class IdInfo
{
public int IdNumber; public IdInfo(int IdNumber)
{
this.IdNumber = IdNumber;
}
} public class Person
{
public int Age;
public string Name;
public IdInfo IdInfo; //浅表复制
public Person ShallowCopy()
{
return (Person)this.MemberwiseClone();
} //深入复制
public Person DeepCopy()
{
Person other = (Person)this.MemberwiseClone();
other.IdInfo = new IdInfo(this.IdInfo.IdNumber);
return other;
}
} class Program
{
public static void DisplayValues(Person p)
{
Console.WriteLine("Name:{0:s} , Age:{1:d}",p.Name,p.Age);
Console.WriteLine("Value:{0:d}",p.IdInfo.IdNumber);
} static void Main(string[] args)
{
//创建一个Person对象
Person p1 = new Person();
p1.Age = ;
p1.Name = "Sam";
p1.IdInfo = new IdInfo(); //复制p1给p2
Person p2 = (Person)p1.ShallowCopy(); //展示这些值
Console.WriteLine("p1实例的值");
DisplayValues(p1);
Console.WriteLine("p2实例的值");
DisplayValues(p2); Console.WriteLine("===========改变p1值的属性并展示p1和p2的值的时候==========="); //改变p1值的属性并展示p1和p2的值的时候
p1.Age = ;
p1.Name = "Frank";
p1.IdInfo.IdNumber =;
Console.WriteLine("p1实例的值");
DisplayValues(p1);
Console.WriteLine("p2实例的值");
DisplayValues(p2); //从结果可以看出,浅表复制由于引用类型复制了对象的引用,当该浅表中所对应原本对象的引用值发生改变时,则浅表中引用类型值
//也会发生改变,而原对象的值类型发生改变时,浅表中值类型的值却不会改变 Console.WriteLine("===========创建一个深入复制的对象给p3==========="); //创建一个深入复制的对象给p3
Person p3 = p1.DeepCopy();
p1.Name = "Gergoe";
p1.Age = ;
p1.IdInfo.IdNumber = ;
Console.WriteLine("p1实例的值");
DisplayValues(p1);
Console.WriteLine("p3实例的值");
DisplayValues(p3); //从结果可以看出,深入复制是把原对象的引用类型也进行了复制,也就是说,把原对象的引用类型字段重新new了...! Console.ReadLine(); //以上代码结果:
//p1实例的值
//Name:Sam , Age:42
//Value:5042
//p2实例的值
//Name:Sam , Age:42
//Value:5042
//===========改变p1值的属性并展示p1和p2的值的时候===========
//p1实例的值
//Name:Frank , Age:32
//Value:7080
//p2实例的值
//Name:Sam , Age:42
//Value:7080
//===========创建一个深入复制的对象给p3===========
//p1实例的值
//Name:Gergoe , Age:22
//Value:6660
//p3实例的值
//Name:Frank , Age:32
//Value:7080
}
}

MemberwiseCopy区别深入复制

  b.Finalize 在垃圾回收器判断对象是否被作为垃圾回收之后,在该对象的实际地址被回收之前,会调用这个虚方法

4.CLR要求new创建对象 

 Employee employee = new Employee("ConstructorParam1");

然而,new需要做的工作是:

  a.它计算类型及其所有基类型( 一直到System.Object )中定义字段所需的字节数.堆上每个成员都需要一些overhead成员,即开销成员——"类型对象指针"( type object pointer )和"同步块索引"( sync block index ).这些成员由CLR共同管理对象.这些额外成员的字节数会计入对象大小.

  b.它从托管中分配指定类型要求的字节数,从而分配对象的内存,分配所有字节都设为零.

  c.初始化"类型对象指针"和"同步化索引块"

  d.调用类型的实例构造器.

注:引用类型有除了实例字段开销之外,还包括两个字段的开销,即"同步化索引块"和"类型对象指针".

5.类型转换 ( 看父不看子 )

  CLR最重要的特性就是类型安全性.在运行时,CLR总是知道一个对象是什么类型.调用GetType方法,总是知道一个对象确切的类型是什么.由于这个方法是非虚方法(不能重写覆盖),所以一个类型不能伪装成另一个类型.这句话很好理解,一个Employee类不能重写GetType方法,所以不能返回一个其他类型,比如SuperHero类型.

  C#不要求任何特殊语法即可将一个对象转化为它的任何基类型,因为基类型转换被认为是一种安全的隐式转换.然而,将对象转化为它的某个派生类型时,C#要求只能进行显式转换,因为这样的转换可能在运行时失败.

  注:声明方法参数类型的最好方法是将参数类型指定,而不是Object,这避免了运行时错误,将错误提早到编译时.

6.使用C#的 is 和 as 操作符来转型

  使用 is 检查一个对象是否兼容于指定的类型,并返回一个 boolean 值: true 或 false . ( is 永远也不会抛出异常 ).

  如果对象的引用是 null , is 操作符总是返回 false ,因为没有可供检查的对象.

  is 操作符的使用:

 if( o is Employee )
{
Employee e = (Employee) o;
...
}

  在上面这段代码中,CLR实际上会检查两次对象的类型. is 操作符首先核实 o 是否兼容于 Employee 类型. 如果是,那么在 if 语句内部执行转型时,CLR再次核实 o 是否引用一个Employee.这无疑造成了性能的损失.

  因为CLR必须判断 变量o 引用的实际类型,然后CLR必须遍历继承层次结构,用 o 的每个基类型去核对每个指定的类型 Employee.

  所以,C#提供了另一个操作符 as ,目的是简化这段代码操作 ,并提升其性能 .

 Employee e = o as Employee;
if( null != e )
{
...
}

  在这段代码中,CLR核实 o 是否兼容 Employee 类型 ;如果是,则 as 会返回对同一个对象的非 null 引用.如果 o 不兼容 Employee 类型, as 操作符会返回 null .

  检查是否为 null 比校验一个对象的类型要效率的多.

  同样, as 操作符也不会抛出异常.

  

7.命名空间和程序集

  命名空间用于逻辑性分组;

    CLR不知道命名空间的任何事,访问一个类型时,CLR需要知道类型的完整名称以及该类型具体定义在哪个程序集中.

  创建命名空间别名:

 using Microsoft;            //尝试添加"Microsoft."前缀
using Wintellect; //尝试添加"Wintellect."前缀 //将WintellectWidget符号定义成Wintellect.Widget的别名
using WintellectWidget = Wintellect.Widget; public sealed class Program
{
public static void main()
{
//使用别名创建对象
WintellectWidget w = new WintellectWidget();
}
}

命名空间别名

 namespace CompanyName
{
public sealed class A { //TypeOf : Company.A
...
} namespace X{
public sealed class B { ... } //TypeOf : CompanyName.X.B
}
}

命名空间规则

  

类型基础---CLR Via C#笔记一的更多相关文章

  1. CLR-基元类型以及溢出检查 (CLR-Via-C#) 类型基础

    CLR-基元类型以及溢出检查   =========(CLR via C#阅读笔记)======== 基元类型(primitive type): 基元类型也不做过多的解释,举个例子即可清晰的辨别 在j ...

  2. [Clr via C#读书笔记]Cp4类型基础

    Cp4类型基础 Object类型 Object是所有类型的基类,有Equals,GetHashCode,ToString,GetType四个公共方法,其中GetHashCode,ToString可以o ...

  3. C#学习笔记——面向对象、面向组件以及类型基础

    C#学习笔记——面向对象.面向组件以及类型基础 目录 一 面向对象与面向组件 二 基元类型与 new 操作 三 值类型与引用类型 四 类型转换 五 相等性与同一性 六 对象哈希码 一 面向对象与面向组 ...

  4. [CLR via C#]4. 类型基础及类型、对象、栈和堆运行时的相互联系

    原文:[CLR via C#]4. 类型基础及类型.对象.栈和堆运行时的相互联系 CLR要求所有类型最终都要从System.Object派生.也就是所,下面的两个定义是完全相同的, //隐式派生自Sy ...

  5. 《C#从现象到本质》读书笔记(三)第3章C#类型基础(下)

    <C#从现象到本质>读书笔记第3章C#类型基础(下) 常量以关键字const修饰.C#支持静态字段(类型字段)和实例字段. 无参属性的get方法不支持参数,而有参属性的get方法支持传入一 ...

  6. 《C#从现象到本质》读书笔记(二)第2章 C#类型基础(上)

    <C#从现象到本质>读书笔记第二篇 第2章 C#类型基础(上) 类型指的是集合{类,结构,接口,枚举,委托}中的任意一个成员.任何拥有某类型的值(value)称为某类型的一个实例(inst ...

  7. 重温CLR(三)类型基础

    所有类型都从System.Object派生 “运行时”要求每个类型最终都要从System.Object类型派生.也就是说,一下两个类型的定义完全一致. //隐式派生自Object class Empl ...

  8. C# 类型基础——你可能忽略的技术细节

    引言 本文之初的目的是讲述设计模式中的 Prototype(原型)模式,但是如果想较清楚地弄明白这个模式,需要了解对象克隆(Object Clone),Clone 其实也就是对象复制.复制又分为了浅度 ...

  9. C# 类型基础

    引言 本文之初的目的是讲述设计模式中的 Prototype(原型)模式,但是如果想较清楚地弄明白这个模式,需要了解对象克隆(Object Clone),Clone其实也就是对象复制.复制又分为了浅度复 ...

随机推荐

  1. Matlab 绘制三维立体图(以地质异常体为例)

    前言:在地球物理勘探,流体空间分布等多种场景中,定位空间点P(x,y,x)的物理属性值Q,并绘制三维空间分布图,对我们洞察空间场景有十分重要的意义. 1. 三维立体图的基本要件: 全空间网格化 网格节 ...

  2. 一步一步教你用CSS画爱心

    今天小颖给大家分享一个用CSS画的爱心,底下有代码和制作过程,希望对大家有所帮助. 第一步: 先画一个正方形.如图: <!DOCTYPE html> <html> <he ...

  3. 协议森林16 小美的桌号(DHCP协议)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 转载请先与我联系. DHCP协议用于动态的配置电脑的网络相关参数,如主机的IP地址,路由器出口地址.DNS域名服务器地 ...

  4. 从零开始编写自己的C#框架(24)——测试

    导航 1.前言 2.不堪回首的开发往事 3.测试推动开发的成长——将Bug消灭在自测中 4.关于软件测试 5.制定测试计划 6.编写测试用例 7.执行测试用例 8.发现并提交Bug 9.开发人员修复B ...

  5. ASP.NET Core 1.0 使用 Dapper 操作 MySql(包含事务)

    操作 MySql 数据库使用MySql.Data程序包(MySql 开发,其他第三方可能会有些问题). project.json 代码: { "version": "1. ...

  6. 实现一个类 RequireJS 的模块加载器 (二)

    2017 新年好 ! 新年第一天对我来说真是悲伤 ,早上兴冲冲地爬起来背着书包跑去实验室,结果今天大家都休息 .回宿舍的时候发现书包湿了,原来盒子装的牛奶盖子松了,泼了一书包,电脑风扇口和USB口都进 ...

  7. 【HanLP】HanLP中文自然语言处理工具实例演练

    HanLP中文自然语言处理工具实例演练 作者:白宁超 2016年11月25日13:45:13 摘要:HanLP是hankcs个人完成一系列模型与算法组成的Java工具包,目标是普及自然语言处理在生产环 ...

  8. iOS有关横向TableView的东西

    之前看到Apple store里面有横向的tableview,当然也有可能是collectionview啦. 尤其是项目中只有一条那么需要横向滑动的东西,就没有必要使用庞大的collectionvie ...

  9. Hadoop学习之旅二:HDFS

    本文基于Hadoop1.X 概述 分布式文件系统主要用来解决如下几个问题: 读写大文件 加速运算 对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整 ...

  10. XAMARIN ANDROID 二维码扫描示例

    现在二维码的应用越来越普及,二维码扫描也成为手机应用程序的必备功能了.本文将基于 Xamarin.Android 平台使用 ZXing.Net.Mobile  做一个简单的 Android 条码扫描示 ...