【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine()
2014-02-05 17:18
811 查看
目录:
【C#小知识】C#中一些易混淆概念总结
这几天在温习结构体和类的时候遇到一个问题。发现一个奇怪的现象,一直找不到合理的答案。但是今天终于找到了合理的答案,所以拿来和大家分享一下。
我们首先来看下面的一段代码:
当我们只是声明一个类和一个结构体的时候,我们的编译器顺利的编译通过。并且打印出结果如下:
为什么我们没有在结构和类中做任何操作,却可以打印出结果,且是“命名空间+"."+数据类型”呢?
首先我查阅了MSDN的关于结构(struct)的官方文档(地址点击这里),有如下的一段话:
结构默认的构造函数(如果没有显式声明)在实例化的时候才会被调用。所以,
在内存中是如下的情况:
此时在栈中已经存在了p这个对象,但是不可用。
那么为什么会打印出“命名空间+"."+数据类型”的结果呢?
我们先看一下VS编译后的中间代码,即Msil,详细解释在图中给出:
有中间语言代码,我们可以知道,最后调用的是Console.WriteLine(Object)方法
这时候就要深入的研究一下Console类了,用反编译工具.NET Reflector查看Console类,因为在上面的代码中,传进.WriteLine()方法的是一个类,所以,我们要查看它的的(object value)方法,如下图:
这时候,我们再深入到WriteLine()方法中去,源代码,如下:
再看Out.WriteLine()的源代码:
因为p已经在栈中创建了对象(但是不可用),所以,直接进入else语句。
明显的可以发现IFormattable是一个接口,我们再看IFormattable接口的源码,如下:
显然我们的Point 结构没有实现一个ToString()方法,不存在继承关系,所以会转化失败,返回一个null值,又进入下一个else语句
这时候最重要的就要来了,我们看到value值被转换为字符串输出了,在看ToString()源代码,如下:
很明显的发现,是获取该对象的数据类型并且转化为字符串输出。如下代码:
打印结果:
这样对结构和类的了解有没有更深入的了解呢?
毕业实习交流群:221376964。你也可以关注我的新浪微博进行交流。
【C#小知识】C#中一些易混淆概念总结
【C#小知识】C#中一些易混淆概念总结(二)
【C#小知识】C#中一些易混淆概念总结(三)
----------------------------------分割线--------------------------------------这几天在温习结构体和类的时候遇到一个问题。发现一个奇怪的现象,一直找不到合理的答案。但是今天终于找到了合理的答案,所以拿来和大家分享一下。
我们首先来看下面的一段代码:
class Program { static void Main(string[] args) { Point p; Console.WriteLine(p); Point p1 = new Point(); Console.WriteLine(p1); Console.ReadKey(); } } //定义结构 struct Point { ////定义时赋初始值,编译器会报错 //private int x; //public Point() //{ } } class Person { //在类中我们可以为属性赋初始值 //private int nAge = 5; //public int NAge //{ // get { return nAge; } // set { nAge = value; } //} }
当我们只是声明一个类和一个结构体的时候,我们的编译器顺利的编译通过。并且打印出结果如下:
为什么我们没有在结构和类中做任何操作,却可以打印出结果,且是“命名空间+"."+数据类型”呢?
首先我查阅了MSDN的关于结构(struct)的官方文档(地址点击这里),有如下的一段话:
结构默认的构造函数(如果没有显式声明)在实例化的时候才会被调用。所以,
//结构的实例化可以不使用NEW关键字,只是将p加载到栈空间中,但是对象不可用,这里没有调用默认的构造函数 Point p2; Console.WriteLine(p2); Console.WriteLine(p2); Console.ReadKey();
在内存中是如下的情况:
此时在栈中已经存在了p这个对象,但是不可用。
那么为什么会打印出“命名空间+"."+数据类型”的结果呢?
我们先看一下VS编译后的中间代码,即Msil,详细解释在图中给出:
有中间语言代码,我们可以知道,最后调用的是Console.WriteLine(Object)方法
这时候就要深入的研究一下Console类了,用反编译工具.NET Reflector查看Console类,因为在上面的代码中,传进.WriteLine()方法的是一个类,所以,我们要查看它的的(object value)方法,如下图:
这时候,我们再深入到WriteLine()方法中去,源代码,如下:
再看Out.WriteLine()的源代码:
因为p已经在栈中创建了对象(但是不可用),所以,直接进入else语句。
明显的可以发现IFormattable是一个接口,我们再看IFormattable接口的源码,如下:
显然我们的Point 结构没有实现一个ToString()方法,不存在继承关系,所以会转化失败,返回一个null值,又进入下一个else语句
else { this.WriteLine(value.ToString()); }
这时候最重要的就要来了,我们看到value值被转换为字符串输出了,在看ToString()源代码,如下:
很明显的发现,是获取该对象的数据类型并且转化为字符串输出。如下代码:
Point p; //打印出p的数据类型 Console.WriteLine(p.GetType()); Point p2; Console.WriteLine(p2); //使用NEW实例化了对像,调用了默认的构造函数 Point p1 = new Point(); Console.WriteLine(p1); Console.ReadKey();
打印结果:
这样对结构和类的了解有没有更深入的了解呢?
毕业实习交流群:221376964。你也可以关注我的新浪微博进行交流。
相关文章推荐
- 【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine()
- 【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine() 分类: C# 2014-02-05 17:18 1060人阅读 评论(0) 收藏
- 【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine()
- C# List集合转换成DataTable
- [转载]C#多线程学习(一) 多线程的相关概念
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 成熟组件化运行效果分解
- C#代码示例_调试
- [转载]C# HashTable 遍历与排序
- [转载]C# 多选功能(checkedListBox控件)
- C#调用dll,字符串参数传过去只有一个字符
- C#添加C项目以及其dll引用不成功
- C#实现邮件发送
- C#代码示例_函数
- C#文件操作类
- C#操作xml工具类
- C#压缩图片算法
- c# enum
- c#判断特殊字符?
- C# Common Keyword
- C# Keynote