解读经典《C#高级编程》第七版 Page20-32.核心C#.Chapter2
前言
讲到核心C#的语法,其实很难讲,因为大部分是基础知识。如果只讲入门的基础知识,那细节又多,意义也不大。我们就不讲一般性的内容,而是找一些有趣的点,展开讲讲。
01
Hello World
Hello World
一般开始编程的开头,都是写一个Hello World程序,这本书也是不能免俗。我们发现,Hello World基本都是用控制台(Console)程序写的。为什么是控制台程序?控制台程序只是一个测试用,学习用的框架吗?并不是这样。了解Java程序的同学可能都会发现,很多Java程序运行起来都是一个黑乎乎的控制台程序,年代越早这种情况越普遍。现在比较少了,毕竟体验不好,逐渐用UI或者系统Service代替。但控制台还是很强大的,在Windows面世之前,所有的程序都是控制台程序,比如用Foxpro开发的财务记账系统。而现在这种控制台程序也很多,Java方面更多,因为Java要跨平台,就相对的重功能轻UI。现在做前端开发,标配都会有不少叫XXX-CLI的控制台工具,用于生成脚手架代码。
程序入口
为什么控制台程序入口是Main()方法?我们知道,程序都需要入口,而不同类型的程序,入口都不同,比如控制台、Winform程序是Main()方法,而asp.net程序是Application_Start()方法。
编译器
Csc.exe是什么?它是C#的命令行编译器程序,我们可以将Visual Studio(以下简称VS)理解为就是集成了一大堆包括csc.exe这类控制台程序而形成的一个大工具系统。类同Java,Java的编译器程序是javac.exe,java编译完成后的代码文件是*.class文件,运行*.class文件需要另外一个控制台程序java.exe,即用命令行执行java.exe xxx.class。而.Net有所不同,csc.exe编译完成后是一个可执行的exe程序(或者类库*.dll),微软的Windows革了控制台的命,所以我们用微软的工具时天然的会感觉到去控制台化,比如VS,体验好到.Net程序员不愿意去做Java开发。
Static
Main()方法为什么是静态的(static)?我们会发现,不管是Java,C#,Main方法都是静态方法,这给初学者其实带来一定的迷惑性。我想,不能说程序入口必须用静态方法,因为“在比特世界里,没有代码实现不了的事情”,而是因为使用静态方法是“最好的入口设计”。我们用对象化的人类语言来模拟程序的启动,它应该是这样描述:
程序.启动();
用C#控制台程序代码实现的就是:
Program.Main();
我们会发现,这样一来Main()就应该是一个Program类的静态方法。那为什么不先var p = new Programm(),在调用p.Main()?因为程序启动只应该是为了“启动”,而不是为了new一个对象,new一个对象可能会带来副作用,比如new一个对象会附带着对对象的初始化,而对象的初始化又带着一堆构造器代码,而这并不是程序“启动”该做的事情。因此静态的Main()方法是最好的设计。
02
变量
变量定义
C#的变量定义,使用前必须初始化。这是学Java的,为了程序的强壮性和安全性。 但同时,这句话是有前提的,是“方法中的变量,必须初始化后才能使用。”而类定义中的字段呢?并不需要。为什么??其实很简单,我们设计一门语言,它的本质是工具,是为了方便开发者,而不是给开发者添堵来的。这句话作为第一性原理,可以应用到理解语言的方方面面。假如你设计了一个类,还要在类的构造方法里逐个初始化类的所有字段,你是不是要发疯?所以类在new的时候,它的字段会自动被赋予“类型的默认值”。比如int就是0,string就是null。取得一个类型的默认值,我们可以用比如:
var value = default(int);
这样写在实际开发中几乎用不到,但等到我们后面再定义泛型类的时候,defalt(T),可能是必须用到的,用来取得一个类型的默认值。
而为什么方法中的变量会必须有默认值呢?我想语言的设计者,应该是认为:“你写一段代码,要定义一个变量,就应该是知道应该给变量初始化什么值,才能使这段代码运行的最安全和保持健壮”。
类型推断
C#定义变量时,可以让编译器进行类型推断,而不明确声明类型,比如:
var endDateTemp = endDate.Value.AddDays(1);
类型推断var是个好东西。作为一个完美主义,我初学C#时,把握不好该不该用var?用var明显不好的一点是,阅读性不够好,你不知道定义的这个类型是什么类型,在VS中,你需要用鼠标移到变量上,才能看到这个变量的类型是什么。所以曾经有一段时间,我强烈的拒绝用var,变量定义类型必须手写。然鹅我现在已经定义变量几乎都用var了。因为要使用太多的类,在现代强类型开发的风潮之下,类的名称又往往很长,手写将大大影响开发效率。实际上,写这么多var,并没有给我带来之前我担心的困扰,反而写的很顺,很爽。但作为完美主义的我,还是坚持在某些情况下,不使用var,因为我坚信:“任何好东西,都是不能滥用的”。所以,“在不影响开发效率的前提下,不使用var”,就是我的一直秉承的原则。我一般原则是:
- 如果接收一个方法的返回值,我一般用var
- 定义并new一个对象,我一般不用var;定义基础类型和string,我基本不用var
变量作用域
作用域不详述。不过我分享一个我使用花括号来避免变量作用域冲突的小技巧,有点意思。
常量 const
常量不详述。不过有句话很有意思,“常量总是静态的”,但这不仅仅是理解为定义常量时不需要使用static,而是它具有static变量定义的本质,就是“数据只有一份”。所以我们可以畅想一下,如果定义了一个类User,这个类中定义了一个int常量字段,那么不管这个类创建了1个还是100个,它们使用的这个常量始终只有一份,存储在堆栈中。
下一篇,讲预定义类型。
觉得文章有意义的话,请动动手指,分享给朋友一起来共同学习进步。
欢迎关注本人微信公众号,更及时的关注最新文章(每周三篇原创文章,以及多篇专题文章):
附文:
上一篇:解读经典-《C#高级编程》第七版-Chapter1-.Net体系结构-Page13-20
解读经典《C#高级编程》第七版 Page20-32.核心C#.Chapter2的更多相关文章
- c#高级编程第七版 学习笔记 第一章 .NET体系结构
第一章 .NET体系结构 本章内容: 编译和运行面向.NET的代码 Microsoft中间语言(Microsoft Intermediate Language,MSIL或简称IL)的优点 值 ...
- c#高级编程第七版 学习笔记 第二章 核心c#
第二章 核心C# 本章内容: 声明变量 变量的初始化和作用域 C#的预定义数据类型 在c#程序中使用条件语句.循环和跳转语句执行流 枚举 名称空间 Main()方法 基本的命令行c#编译器选项 使用S ...
- c#高级编程第七版 学习笔记 第三章 对象和类型
第三章 对象和类型 本章的内容: 类和结构的区别 类成员 按值和按引用传送参数 方法重载 构造函数和静态构造函数 只读字段 部分类 静态类 Object类,其他类型都从该类派生而来 3.1 类和结构 ...
- C#高级编程第9版 第二章 核心C# 读后笔记
System命名空间包含了最常用的.NET类型.对应前面第一章的.NET基类.可以这样理解:.NET类提供了大部分的功能,而C#语言本身是提供了规则. pseudo-code,哈哈,秀逗code.伪代 ...
- ASP.NET MVC 4高级编程(第4版)
<ASP.NET MVC 4高级编程(第4版)> 基本信息 作者: (美)Jon Galloway Phil Haack Brad Wilson K. Scott All ...
- 《UNIX环境高级编程(第3版)》
<UNIX环境高级编程(第3版)> 基本信息 原书名:Advanced Programming in the UNIX Environment (3rd Edition) (Addison ...
- 【转】apue《UNIX环境高级编程第三版》第一章答案详解
原文网址:http://blog.csdn.net/hubbybob1/article/details/40859835 大家好,从这周开始学习apue<UNIX环境高级编程第三版>,在此 ...
- Linux - Unix环境高级编程(第三版) 代码编译
Unix环境高级编程(第三版) 代码编译 本文地址:http://blog.csdn.net/caroline_wendy 时间:2014.10.2 1. 下载代码:http://www.apuebo ...
- Unix环境高级编程第三版中实例代码如何在自己的linux上运行的问题
学习Linux已经有2个月了,最近被期末考试把进度耽误了,前几天把Unix环境高级编程看了两章,感觉对Linux的整体有了一些思路,今天尝试着对第一章涉及到的一个简单的交互式shell编译运行一下,结 ...
- C#高级编程笔记之第二章:核心C#
变量的初始化和作用域 C#的预定义数据类型 流控制 枚举 名称空间 预处理命令 C#编程的推荐规则和约定 变量的初始化和作用域 初始化 C#有两个方法可以一确保变量在使用前进行了初始化: 变量是字段, ...
随机推荐
- Adnroid开发环境搭建(四步搞定)
新手博友,多多关照 下面给大家介绍JDK Eclipse AndroidSDK ADT环境搭建,安装教程 第一步.安装JDK: 第二步.安装Eclipse: 第三步.下载并安装AndroidSDK: ...
- 【repost】js window对象属性和方法相关资料整理
window对象有以下方法: open close alert confirm prompt setTimeout clearTimeout setInterval clearInterval mov ...
- Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/ma ven/cli/Maven
此异常是由于jdk版本和maven版本不一致导致的 在maven官网上的说明是这样的:Maven 3.3+ require JDK 1.7 or above to execute - they sti ...
- VSCode 必装的 10 个高效开发插件 --转
https://www.cnblogs.com/parry/p/vscode_top_ten_plugins.html
- #254 Check for Palindromes
Check for Palindromes 检查回文字符串 如果给定的字符串是回文,返回true,反之,返回false. 如果一个字符串忽略标点符号.大小写和空格,正着读和反着读一模一样,那么这个字符 ...
- La protezione del puntatore laser
Questo puntatore laser è sempre sufficientemente efficiente per eseguire il test più accurato su qua ...
- Asp.net Security框架(1)
Security框架主要用于身份认证的,基本上所有Asp.net项目有意或者无意的都在使用的,框架的源码包含在Katana项目下. 最常见的使用方式或许就是SignIn来给客户端浏览器生成包含身份信息 ...
- dcloud 近期遇到的小知识一览
1.form-data时,请求头改变为application/x-www-form-urlencoded. 2.下拉刷新,首先在page.json里面的style将enablePullDownRefr ...
- Javascript高级编程学习笔记(80)—— 表单(8)表单序列化
表单序列化 随着 Ajax 的出现,表单序列化成为一种常见需求 以将表单信息序列化为查询字符串为例 我们可以利用表单的 type 属性,以及 name 和 value 实现对表单的序列化 序列化应满足 ...
- 第46节:Java当中的常量池
Java当中的常量池 在Java虚拟机jvm中,内存分布为:虚拟机堆,程序计数器,本地方法栈,虚拟机栈,方法区. 程序计数器是jvm执行程序的流水线,是用来存放一些指令的,本地方法栈是jvm操作系统方 ...