前言

讲到核心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”,就是我的一直秉承的原则。我一般原则是:

  1. 如果接收一个方法的返回值,我一般用var
  2. 定义并new一个对象,我一般不用var;定义基础类型和string,我基本不用var

变量作用域

作用域不详述。不过我分享一个我使用花括号来避免变量作用域冲突的小技巧,有点意思。

常量 const

常量不详述。不过有句话很有意思,“常量总是静态的”,但这不仅仅是理解为定义常量时不需要使用static,而是它具有static变量定义的本质,就是“数据只有一份”。所以我们可以畅想一下,如果定义了一个类User,这个类中定义了一个int常量字段,那么不管这个类创建了1个还是100个,它们使用的这个常量始终只有一份,存储在堆栈中。

下一篇,讲预定义类型。

觉得文章有意义的话,请动动手指,分享给朋友一起来共同学习进步。

欢迎关注本人微信公众号,更及时的关注最新文章(每周三篇原创文章,以及多篇专题文章):

附文:

C# 翻身?微软重写开源的 C# 编译器!

C#中变量的作用域

上一篇:解读经典-《C#高级编程》第七版-Chapter1-.Net体系结构-Page13-20

解读经典《C#高级编程》第七版 Page20-32.核心C#.Chapter2的更多相关文章

  1. c#高级编程第七版 学习笔记 第一章 .NET体系结构

    第一章      .NET体系结构 本章内容: 编译和运行面向.NET的代码 Microsoft中间语言(Microsoft Intermediate Language,MSIL或简称IL)的优点 值 ...

  2. c#高级编程第七版 学习笔记 第二章 核心c#

    第二章 核心C# 本章内容: 声明变量 变量的初始化和作用域 C#的预定义数据类型 在c#程序中使用条件语句.循环和跳转语句执行流 枚举 名称空间 Main()方法 基本的命令行c#编译器选项 使用S ...

  3. c#高级编程第七版 学习笔记 第三章 对象和类型

    第三章 对象和类型 本章的内容: 类和结构的区别 类成员 按值和按引用传送参数 方法重载 构造函数和静态构造函数 只读字段 部分类 静态类 Object类,其他类型都从该类派生而来 3.1 类和结构 ...

  4. C#高级编程第9版 第二章 核心C# 读后笔记

    System命名空间包含了最常用的.NET类型.对应前面第一章的.NET基类.可以这样理解:.NET类提供了大部分的功能,而C#语言本身是提供了规则. pseudo-code,哈哈,秀逗code.伪代 ...

  5. ASP.NET MVC 4高级编程(第4版)

    <ASP.NET MVC 4高级编程(第4版)> 基本信息 作者: (美)Jon Galloway    Phil Haack    Brad Wilson    K. Scott All ...

  6. 《UNIX环境高级编程(第3版)》

    <UNIX环境高级编程(第3版)> 基本信息 原书名:Advanced Programming in the UNIX Environment (3rd Edition) (Addison ...

  7. 【转】apue《UNIX环境高级编程第三版》第一章答案详解

    原文网址:http://blog.csdn.net/hubbybob1/article/details/40859835 大家好,从这周开始学习apue<UNIX环境高级编程第三版>,在此 ...

  8. Linux - Unix环境高级编程(第三版) 代码编译

    Unix环境高级编程(第三版) 代码编译 本文地址:http://blog.csdn.net/caroline_wendy 时间:2014.10.2 1. 下载代码:http://www.apuebo ...

  9. Unix环境高级编程第三版中实例代码如何在自己的linux上运行的问题

    学习Linux已经有2个月了,最近被期末考试把进度耽误了,前几天把Unix环境高级编程看了两章,感觉对Linux的整体有了一些思路,今天尝试着对第一章涉及到的一个简单的交互式shell编译运行一下,结 ...

  10. C#高级编程笔记之第二章:核心C#

    变量的初始化和作用域 C#的预定义数据类型 流控制 枚举 名称空间 预处理命令 C#编程的推荐规则和约定 变量的初始化和作用域 初始化 C#有两个方法可以一确保变量在使用前进行了初始化: 变量是字段, ...

随机推荐

  1. 基于接口的 InvocationHandler 动态代理(换种写法)

    InvocationHandler is the interface implemented by the invocation handler of a proxy instance. Each p ...

  2. 在windows下golang安装zmq3小记

    备忘这个 安装 TDM-GCChttp://tdm-gcc.tdragon.net/download 设置环境变量set C_INCLUDE_PATH=d:\DevTools\Zmq\ZeroMQ 3 ...

  3. alfred3配置

    搜索功能配置 github https://github.com/search?utf8=%E2%9C%93&q={query} github'{query}' g baidu http:// ...

  4. HTTP 初步探究

    网络上存在很多资源,也持续不断地生成新的资源.为了新建.获取和操作这些资源,引来了两个问题:如何定位资源,如何对他们进行操作.第一个问题引申出了 URI / URL 即 uniform resourc ...

  5. HelloWorld带我入门JAVA(一)

    基本环境配置可以百度完成,给个比较全面的网址http://c.biancheng.net/java/10/ 创建第一个java工程 通过Eclipse运行程序 启动Eclipse,在菜单中选择“文件 ...

  6. day18_雷神_django第一天

    # django_day01 1.http 协议 超文本传输协议,HTTP有很多应用,但最著名的是用于web浏览器和web服务器之间的双工通信. 协议概述 HTTP是一个客户端终端(用户)和服务器端( ...

  7. Appium + Java 测试 [百度地图] APP的一段简单脚本

    1. 流程 进入 app ,手动处理前段预处理,程序一直等候到达指定搜索地名页面,填入[南通大学],点击[搜索] 2. Java 脚本 // part 1: 引入需要的包 import io.appi ...

  8. BCrypt加密算法

    用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串(如域名)加密,然后再使用一个随机的salt(盐值)加密. 特定字符串是程序代码中固定的,salt是每个密码 ...

  9. Chart 图表开源项目总结

    在Android开发中,我们不免会遇到图表展示的需求,以下是本人之前star的悬浮窗的开源项目,供大家参考: 1. WilliamChart:创建图表的Android库 2. HelloCharts: ...

  10. Javascript高级编程学习笔记(34)—— 客户端检测(3)用户代理检测

    用户代理检测 前面的文章介绍的是如何检测浏览器对某一功能的支持情况 但是在实践中我们有些时候免不了需要知道用户到底是用的什么浏览器对我们的站点进行访问 这也是统计用户行为的一部分 用户代理检测这种方式 ...