一、做好准备
亲爱的读者,欢迎您开始学习编程之旅!电脑、平板电脑、手机和许多其他电子设备都是可编程的,会完全按照人类程序员告诉他们的去做。
编程是一个完全基于逻辑的世界。在这方面,它在人类活动中是独一无二的。如果你喜欢逻辑——例如,你喜欢解谜或者你习惯于寻找你周围有意义的秩序——那么你会喜欢编程。
C# 语言
在本书中,您将创建一些真正的程序,为此,您需要学习一种编程语言,这种语言为计算机提供指令。编程语言提供了计算机和人类之间的交互。它们足够严格,以至于绝对愚蠢的计算机可以理解它们,但它们也足够人性化,以至于程序员可以使用它们编写代码。
随着时间的推移,许多编程语言被创造出来,并且有许多在今天被使用。每种语言都有其优点和缺点。
对于这本书,我选择了 C# 编程语言,这是我职业发展和教学的首选语言。它大约有 20 年的历史,这意味着它的创造者在开发它时可以避免旧语言的已知缺陷。此外,它现在是一种经过时间考验的语言,不会轻易被一些新的时尚所取代。
C# 实际上是微软的旗舰语言。它是相当通用的——你可以用它来编写各种程序,从传统的控制台和桌面应用,通过网站和服务到移动开发,无论是商业还是娱乐。它最初诞生于 Windows,近年来迅速传播到其他平台,如 Linux、Mac、Android 和 iOS。
我希望你会有一个美好的时光,你会发现它在你未来的职业/业余生活中有很多用途!
这本书是给谁的
这本书主要是为那些没有或仅有有限编程知识的人准备的。为了从本书中获得最大收益,你应该熟练使用计算机——你应该能够安装程序,知道什么是文件或文件夹,等等。
但是,由于本书对所包含的主题进行了深入的覆盖,如果您是一名中级程序员或已经掌握了另一种编程语言并希望从 C# 开始,您也可能会从本书中受益。你将比完全的初学者更快地阅读这本书。
这本书与其他书有何不同
我写这本书是基于我 15 年来教授各种学生、教师、业余爱好者和其他人编程的经验。对他们中的许多人来说,这是他们第一次接触这个主题。我在工作时密切观察他们,多年来,我积累了大量关于人们如何学习、什么对他们来说容易、什么需要更多关注的信息。
在本书中,你将受益于这些知识。本书与同类书籍的不同之处主要体现在以下几个方面:
-
解释的速度——也就是进入新话题的速度——要适当慢一些,这样你才不会在开始后不久就迷失了方向。专家作者的一个常见谬误是认为初学者的东西微不足道。事实上,这对他们来说是微不足道的。但不是给读者看的。我已经做了相当大的努力来避免这种情况,并花足够的时间在印心者认为容易的事情上。
-
我相信,为了成功地掌握所有的新思想,你需要看到它们在略有不同的情况下反复使用,这就是你在这里找到的。写这些例子是为了让你循序渐进,强化你已经知道的东西,并且总是增加一点新的信息或观点。
-
大量的例子让我即使停留在初级水平也能深入这个主题。许多入门书籍通过一两个教科书上的例子展示了一个新的概念,然后继续前进。这里不是这样的。所选的例子来自真实的编程。它们通常代表了我在开发真实软件时发现自己所处的各种情况的核心。我涵盖了提炼到初级水平的核心主题。
-
我已经用捷克语写了几本编程书籍,并且发现许多读者更喜欢编码示例而不是解释性文本。这大概反映了我们这个信息超载的现代。这就是为什么我用简明的、面向任务的方法写了这本书。你会发现这里说的最少,做的最多。好好享受吧!
如何使用这本书
在我开始告诉你如何准备你的电脑之前,这里有一些关于你如何使用这本书以获得最大效用的提示:
-
这本书包含许多练习。这些不是练习你已经学过的东西的任务。这些任务构成了这本书的主要内容。这意味着你不应该在阅读完任务后试图去解决问题。你应该做的是阅读这个任务是关于什么的,看看它的说明性截图,然后立即去研究它的解决方案。
-
你不应该只是阅读解决方案。强烈建议你在电脑上输入它们并让它们工作。如果你亲自尝试每一件事,这些练习会对你的理解产生更大的影响。
-
如果你不能进行一些练习,你可以在
https://github.com/apress/csharp-programming-for-absolute-begs
查看附带的源代码。此外,你可能想在http://modernizrogramovani.cz/en/
访问我的网站。 -
在每个任务中,试着理解其解决方案的逻辑。此外,尝试自己修改任务也很有帮助。不要害怕使用代码。这不是一个化学实验室;你不能炸掉你的房子!
-
我在解决方案中加入了很多评论。实际上,代码的每个逻辑部分都有一个空行和解释其用途的注释。请密切注意这些评论;它们是主要的暗示,正好位于它们所解释的地方。只有更长的解释,我把它放在了代码之外,放在了书的正文中。
-
在每一章的结尾,你可以放松下来,阅读它的摘要。然后,在进入下一章之前,你可以将它与你所学的主题进行比较。
在你的电脑上安装什么
介绍够了。让我们继续讨论如何准备,或者更确切地说,你应该如何准备你的电脑。
发展环境
要阅读这本书,你需要在电脑上安装一个程序,即所谓的集成开发环境(IDE)。
什么是 IDE?嗯,要在电脑上进行任何活动,你需要合适的软件。要写文字,你要用文字处理器;要浏览网页,你使用浏览器;等等。同样的,为了创建程序,你需要使用专门的软件来简化编程,这个软件就是开发环境。换句话说,它是一个“为编程而编程的程序”。
它通常被称为“集成”开发环境,因为它将程序员的所有活动——使用智能编辑器编写代码、将程序构建成计算机可用的形式、启动和测试程序、查看计算机内存等——都集中到一个地方,并提供工具帮助。
可视化工作室
对于 C# 来说,最好的开发环境是 Visual Studio。在撰写本文时,最新的生产版本是 2019 年,并在一个名为 Community 的免费版本中提供(见图 1-1 )。一分钟后,您将学习如何安装它。在本书中,我将使用 2021 年 1 月发布的 Visual Studio 版本,其中包括计划在下一个生产版本中发布的功能预览。NET 5 平台和 C# 9.0 语言等等。
图 1-1
Visual Studio 社区
Windows 版本
Visual Studio 需要 Windows 操作系统。如果你在网上搜索 Visual Studio 系统需求,你会发现支持的 Windows 版本(见图 1-2 )。
图 1-2
支持的 Windows 版本
如您所见,您不需要安装最新最好的 Windows 版本。截至 2021 年 1 月,您甚至可以安装带有 Service Pack 1 的 Windows 7。
此外,要使用这本书,你甚至不需要最新的 Visual Studio 版本。书中几乎所有的例子都可以在旧版本上很好地运行。
非 Windows 操作系统
如果您的计算机上没有 Windows 操作系统,您会很高兴听到 Visual Studio 代码开发环境。这是一个免费的多平台 IDE,也可以在 Linux 或 Mac 上运行,允许你在这些系统上用 C# 编程。
在本书的例子中,我将使用安装在 Windows 上的 Visual Studio 社区。我建议你也这样做。如果这对您来说不可行,请使用 Visual Studio 代码,同时考虑到有些内容可能与您在书中看到的略有不同。
装置
现在你知道要安装什么了——Visual Studio 社区——所以,请继续吧!将你的网页浏览器指向 http://visualstudio.com
,寻找类似“下载 Visual Studio”的东西,一定要选择“社区”版。单击按钮或链接,安装程序开始下载。
在安装过程中,会出现一个屏幕,显示您可以选择的不同组件(参见图 1-3 )。
图 1-3
安装 Visual Studio
一定要选择”。NET 桌面开发”并单击“安装”按钮。之后,安装应该会顺利运行。
免费注册
安装 Visual Studio 后,您应该在第一次启动它时注册您的副本(免费)。在相应的屏幕上,单击“登录”按钮并输入您的 Microsoft 帐户凭据。如果您还没有微软帐户,只需点击“注册”链接即可获得一个(见图 1-4 )。
图 1-4
注册您的 visual studio 副本
如果您在首次启动 Visual Studio 时跳过此步骤,您可以稍后通过选择“帮助➤在 Visual Studio 中注册产品”来注册。
更新和反馈
信息技术日新月异。在你读这本书的时候,有些事情可能会不同。如果 Visual Studio 出现了重要的变化,您可以通过 http://moderniProgramovani.cz/en/
查看我的网站以获得最新信息。
此外,我欢迎任何关于这本书的反馈——你对它的改进建议,你学习它的感受,你用它教学的经验,等等。我的邮箱是vystavel@moderniProgramovani.cz
。谢谢大家!
摘要
在这本书里,你将学习编程,特别是 C# 编程语言。您将通过许多实践练习学习用 C# 编写代码,这些练习将引导您走向越来越复杂的主题。为了能够按照练习进行,您应该按照以下方式准备您的计算机:
-
您需要一台装有 Windows 操作系统的计算机(至少装有 Service Pack 1 的 Windows 7)。
-
您需要安装一个合适的开发环境。在本书中,我将与免费的 Visual Studio 社区一起工作。
二、你的第一个程序
现在你已经准备好了你的电脑,让我们开始编程吧!在这一章中,你将用 C# 语言创建你的第一个程序,并学习你需要执行的所有步骤。
看到它的实际应用
在这一章中,你将创建一个显示信息“我开始用 C# 编程”的程序给用户(见图 2-1 )。
图 2-1
你的第一个程序
创建项目
你通过创建一个新的项目来开始每一个新的程序,所以让我们现在就开始吧。
启动 Visual Studio
启动 Visual Studio。应出现类似图 2-2 的开始屏幕。
图 2-2
Visual Studio 开始屏幕
向下拖动滚动条,选择“创建新项目”动作(见图 2-3 )。
图 2-4
选择项目模板
图 2-3
为新项目选择
创建新项目
出现的对话框(见图 2-4 )要求您选择一个新的项目模板。选择控制台应用 C# 模板,然后按下一步按钮。
在下一个对话框中(见图 2-5 ),键入“我的第一个程序”作为新的项目名称,并按下创建按钮。
图 2-5
输入新项目的名称
编写程序代码
最重要的步骤是编写程序代码,所以请继续阅读。
开发环境的外观
项目创建后,Visual Studio 看起来如图 2-6 。
图 2-6
Visual Studio 的外观
开发环境窗口的主要部分被源代码编辑器占据。在其中,Program.cs
文件被打开,正如标签的标题所暗示的。Program.cs
是新控制台项目的主文件。如您所见,它已经包含了一些源代码。
您可能想知道这些代码是从哪里来的。你还没有写任何一行代码!答案是,当您选择控制台应用模板时,Visual Studio 生成了代码。正如您在创建项目时看到的,Visual Studio 包含许多不同的模板;这些模板是不同类型程序的现成项目框架。
你可以看到代码中包含了一些奇怪的单词,比如using
、namespace
、class
等等。我现在不打算解释这些,因为此时你不需要详细理解它们。但是 Visual Studio 需要这些行,所以不要管它们。你需要知道的是在哪里写你自己的陈述,这是我接下来要解释的。
知道在哪里写陈述
你在包含单词Main
的行后的花括号中写程序语句(见图 2-7 )。
图 2-7
你写陈述的地方
在所有以前的 Visual Studio 版本中,大括号之间的空间是空白的。现在,IDE 创建者决定包含一行代码,您可以在以后删除或修改它。
编写代码
在这种情况下,在主行后的花括号中键入以下语句**。确保准确地键入您在这里看到的**。小写和大写之间的区别很重要,分号也很重要!****
// Output of text to the user
Console.WriteLine("I am starting to program in C#.");
// Waiting for Enter
Console.ReadLine();
Visual Studio 现在看起来如图 2-8 所示。
图 2-8
输入您的第一个代码语句
请仔细检查你是否和我在同一个地方输入了语句。同样,它们必须在括号之间。另外,要小心括号。不要意外删除其中任何一个。
Program.cs
的源代码现在看起来像这样:
using System;
namespace My_first_program
{
class Program
{
static void Main(string[] args)
{
// Output of text to the user
Console.WriteLine("I am starting to program in C#.");
// Waiting for Enter
Console.ReadLine();
}
}
}
理解你的第一句话
这些语句有什么作用?
-
向用户输出(写)一行。
-
Console.ReadLine
一般来说,读取用户用键盘输入的一行文本。然而,在这种情况下,该语句的目的是让您的程序在一切完成后等待用户按 Enter 键。换句话说,您不希望程序窗口立即消失。 -
两个斜线(
//
)后面的所有内容都将被忽略,直到对应行的末尾。此文本包含您的备注/评论。Visual Studio 将它们涂成绿色。
使用智能感知
您可能已经注意到,当您键入时,Visual Studio 会为您提供可用的可能性(参见图 2-9 )。您可以使用鼠标或使用箭头键然后按 Tab 键来选择一个选项。
图 2-9
使用智能感知
Visual Studio 中为您提供这些提示的部分称为智能感知。尽量习惯依赖它。这是避免不必要的错别字的最好方法。
保存项目
你已经写了几行代码,所以你可能想保存它们。根据 Visual Studio 的默认设置,项目会在每次程序启动前自动保存。但是,有时您希望手动保存更改。在这种情况下,从 Visual Studio 菜单中选择“文件”“➤”“全部保存”,或者单击 Ctrl+S
启动您的程序
写完程序后,你通常希望启动它,看看它是否“运行”,并检查它是否如你所愿。
做好准备。您的第一个计划发布的伟大时刻即将到来!从 Visual Studio 菜单中选择调试➤开始调试,或者直接按 F5 键。
Visual Studio 构建并启动您的程序(参见图 2-10 )。该程序输出指定的文本,并等待按下回车键,这正是你的编程方式。
图 2-10
启动您的程序
现在在用户的角色中,按回车键。程序终止,“黑窗口”消失。实际上,这是 Visual Studio 到目前为止的行为。在目前的版本中,增加了一个新的措施来防止控制台窗口消失,正如你在点击 Enter 键后所看到的那样(图 2-11 )。
图 2-11
防止窗户消失的附加措施
因为Console.ReadLine()
防止窗口在 Visual Studio 之外运行时消失,我将在我们所有的程序中包含这个声明。如果您愿意,您可以根据图 2-11 的消息中给出的说明禁用新的 Visual Studio measure。
在 Visual Studio 中,选择“工具”“➤选项”菜单。在对话框中,点击调试组,然后勾选“调试停止时自动关闭控制台”选项,按 OK 确认(见图 2-12 )。
图 2-12
禁用新度量
注意
根据您计算机的默认设置,您的程序将以黑底白字显示,如图 2-10 所示。然而,为了更好的可读性,我将在浅色背景上以黑色字体显示所有后来的截图(见图 2-11 )。
更改文本大小
你认为输出的文本太小了吗?你需要放大你的程序将要使用的字体吗?
如果是,点击已启动程序“黑屏”左上角的标题栏图标,选择默认(见图 2-13 )。
图 2-13
选择默认设置
然后点击字体选项卡,根据自己的喜好更改字体,点击确定按钮确认更改(见图 2-14 )。
图 2-14
更改字体
下一个程序启动时,将使用新字体。
处理错误
如果您没有按照我向您展示的方式编写语句,或者您将它们写在了错误的位置,程序构建将会因错误而不成功地终止。
让我们试试这个!用Console.WriteLine
语句删除行尾的分号。
当您尝试启动您的程序(通过按 F5 键)时,试验终止,出现错误对话框(参见图 2-15 )。
图 2-15
出现错误
在这个对话框中,总是点击 No;你不想运行某个旧版本的程序(如果它存在的话)。
点击否后,错误列表窗格出现在底部(见图 2-16 )。
图 2-16
错误表
把删除的分号退回去,一切又好了。以后可能更难发现自己做错了什么,尤其是在编程生涯的初期。没关系——我的观点是,除非你犯了所有可能的错误,否则你不可能成为某个领域的专家。
完成你的工作
您已经完成了程序开发的所有基本步骤。在你未来的每一个项目中,你都将沿着同样的路线前进。
你现在需要学习如何终止你的工作,以及如何在以后继续工作。前者简单;您可以通过从菜单中选择“文件”“➤”“关闭解决方案”或关闭整个 Visual Studio 程序来完成此项目的工作。
恢复您的工作
当您稍后想要回到您的项目时,可以使用下列方法之一在 Visual Studio 中重新打开它:
图 2-17
使用起始页
- 从起始页:这是 Visual Studio 启动后立即出现的页面,包含指向您最近项目的链接(参见图 2-17 )。只需点击正确的选项。
图 2-19
显示扩展
图 2-18
用“打开项目”对话框打开程序
- 从打开项目对话框:从 Visual Studio 菜单中选择文件➤打开➤项目/解决方案。打开项目对话框出现,您应该在其中找到您的项目(参见图 2-18 )。具体来说,就是查找扩展名为
.sln
的文件。如果看不到文件扩展名,请在 Windows 文件资源管理器中打开它们的显示(在“查看”选项卡上,选中“文件扩展名”复选框),如图 2-19 所示。
图 2-20
从文件菜单打开您的项目
- 从最近的项目菜单:选择文件➤最近的项目和解决方案。Visual Studio 会记住您最近从事的项目。选择合适的项目即可(见图 2-20 )。
转移您的工作
您可能还对如何将项目从您的电脑传输到其他地方感兴趣,以便您以后可以在不同的电脑上处理它。答案很简单。如果您使用的是闪存驱动器、OneDrive 或类似设备,只需转移项目的整个文件夹。
使用解决方案浏览器
将项目转移到您应该熟悉的另一台计算机上有一个重要问题。有时,项目是在没有源代码编辑器的情况下打开的(见图 2-21 )。
图 2-21
在没有源代码编辑器的情况下打开项目
在这种情况下你会怎么做?有一个名为“解决方案资源管理器”的窗格(子窗口),通常位于 Visual Studio 窗口的右侧。只需双击你的源代码文件Program.cs
(见图 2-22 )。
图 2-22
通过解决方案资源管理器打开源代码
连解决方案资源管理器都消失了吗?没问题!在任何时候,您都可以使用菜单选择视图➤解决方案资源管理器来显示它(参见图 2-23 )。
图 2-23
打开解决方案资源管理器
摘要
在本章中,您编写了自己的第一个程序,并开始学习如何使用 Visual Studio 开发环境。你经历了程序开发的所有步骤,基本上是这样的:
-
创建项目
-
编辑源代码
-
保存源代码
-
启动程序
-
检测和排除可能的错误
-
将您的项目转移到您的另一台电脑上,以便在其他地方使用**
三、处理输出
你已经知道了用 C# 语言开发程序时应该采取的所有主要步骤。此外,您已经看到了重要的语句Console.WriteLine
,它在您的用户屏幕上显示数据。在本章中,您将扩展对这一陈述的了解。我还将向您展示输出的其他可能性。
产生数字输出
您已经知道如何显示一些文本。在本节中,您将学习如何显示数字。
工作
您将编写一个显示数字 37 的程序(参见图 3-1 )。
图 3-1
行动中的计划
解决办法
在 Visual Studio 中,创建名为 Numeric Output 的新项目。代码类似于您在第二章中编写的前一个程序,如下所示:
static void Main(string[] args)
{
// Output of a number to the user
Console.WriteLine(37);
// Waiting for Enter
Console.ReadLine();
}
Note
在本例中,以及本书中的所有后续示例中,我只向您展示了带有Main
单词的行之后的代码块。这是您控制的代码块;换句话说,它是你改变的代码块。其余的Program.cs
源代码应该保持原样,就像你在上一章的第一个程序中那样。
为了确保您理解我的意思,整个源代码看起来像这样:
using System;
namespace Numeric_output
{
class Program
{
static void Main(string[] args)
{
// Output of a number to the user
Console.WriteLine(37);
// Waiting for Enter
Console.ReadLine();
}
}
}
但是,同样,这是你最后一次看到完整的源代码。没有必要在我每次展示一个例子时都重复 Visual Studio 生成的代码,因为您永远不会更改它。如果您有疑问,可以参考本书附带的完整示例项目。
输入代码后,使用 F5 键启动程序。要终止程序,请按回车键。
讨论
与文本不同,数字不用引号括起来。
当然,你可以用引号将“37”括起来,但是数字 37 和文本“37”之间有很大的区别——你可以用数字来计算。这就是为什么你现在正在学习如何正确处理数字。
进行计算
接下来的任务是做一个简单的计算。
工作
你要向用户显示 1 加 1 是多少(见图 3-2 )。
图 3-2
1 加 1
解决办法
代码如下:
static void Main(string[] args)
{
// Output of a calculation
Console.WriteLine(1 + 1);
// Waiting for Enter
Console.ReadLine();
}
输入并启动程序!
注意
在编程中,这种计算(一般是值的组合)称为一个表达式。
进行更复杂的计算
当然,你不需要一台电脑来做 1 对 1 的加法。但是 1 加 2 乘以 3 呢?你觉得这又是可笑的鸡毛蒜皮吗?请稍等片刻,因为即使在这种简单的情况下也很容易出错!
工作
您将创建一个程序来将 1 加 2 乘以 3。
解决办法
代码如下:
static void Main(string[] args)
{
// Multiplication has greater priority
Console.WriteLine(1 + 2*3);
// Forcing priority using parentheses
Console.WriteLine((1 + 2)*3);
// Waiting for Enter
Console.ReadLine();
}
启动后的程序如图 3-3 所示。
图 3-3
做更复杂的计算
讨论
请注意该程序的以下内容:
-
此任务的目的是向您展示,您始终必须知道到底需要计算什么。在这个例子中,你必须决定是先做加法还是先做乘法。
-
在基本的数学规则中,乘法和除法的优先级高于加法或减法。编程和数学是一样的。如果你首先想把 1 加到 2 上,然后乘以 3,你需要用括号把 1 和 2 括起来。
-
我没有在乘法符号(星号)周围使用空格,但这与计算顺序无关。我觉得这样更好。在 C# 中,空格和换行符无关紧要。(当然中间不要断一个字。)
-
最后,该示例显示计算机按照编写的顺序执行程序语句。这意味着自上而下。
连接文本
现在,您将发现加号运算符(+)也可以用于文本,而不仅仅是数字。换句话说,它将文本添加在一起。
工作
任务是探索如何将文本加在一起(见图 3-4 )。
图 3-4
连接文本
解决办法
代码如下:
static void Main(string[] args)
{
// Normal text
Console.WriteLine("I have started to program");
// Also normal text
Console.WriteLine(" in C#.");
// Joining two texts using plus sign
Console.WriteLine("I have started to program" + " in C#.");
// Waiting for Enter
Console.ReadLine();
}
注意介词中前的空格!
输出特殊字符
有时候,你需要输出一个特殊的字符到屏幕上。以下是一些例子:
-
输出回车结束一行。
-
输出引号。(C# 中的引号用作文本分隔符,因此必须特殊对待。)
-
输出一个 Unicode 字符(当然,如果你的字体知道怎么画的话)。
工作
现在你要写一个程序来演示如何处理特殊字符。
解决办法
要处理特殊字符,可以使用转义序列。在 C# 中,转义序列以反斜杠开头。
static void Main(string[] args)
{
// Multiline output
Console.WriteLine("First line\r\nSecond line");
// I prefer specifying "Enter" in more human form
Console.WriteLine("First line" + Environment.NewLine + "Second line");
// Text containing a quote
Console.WriteLine("The letter started so sweet: \"My Darling\"");
// Unicode characters, in this case Greek beta
Console.WriteLine("If the font knows, here is Greek beta: \u03B2");
// Backslashes themselves need to be doubled
Console.WriteLine("Path to desktop on my computer: " + "C:\\Users\\vystavel\\Desktop");
// Waiting for Enter
Console.ReadLine();
}
结果应该如图 3-5 所示。
图 3-5
使用特殊字符
讨论
请注意该程序的以下内容:
-
在 C# 中,文本中的反斜杠引入了所谓的转义序列。但是如果你想输出一个反斜杠呢?那你需要加倍。在 Windows 操作系统中处理文件路径时,经常会出现这种情况。
-
控制台应用甚至会将简单的
\n
识别为行结束符(表示回车)。然而,在许多其他 C# 程序中,您需要“整个回车”,这用\r\n
表示。这就是你在这个程序中使用它的原因。你还使用了Environment.NewLine
,这绝对是最好的选择,因为它可读性很好。
使用预格式化文本
有时,你可能想一次显示多行文本(见图 3-6 )。
图 3-6
多行文本
工作
您将创建一个程序来显示多行文本。
解决办法
在文本的左引号前加上 at ( @
)符号,如下所示:
static void Main(string[] args)
{
// Bob Dylan...
Console.WriteLine(@" Yes, and how many times can a man turn his head and pretend that he just doesn’t see?");
// Waiting for Enter
Console.ReadLine();
}
注意
at ( @
)符号也关闭转义序列。这就是为什么在 Windows 中处理文件路径时你会发现它很有用(前面提到过);在这种情况下,您不必将每个反斜杠都加倍。
将 1 和 1 相加
在下一个任务中,你将回到 1 加 1 的问题。你想知道为什么我要回到如此琐碎的任务上吗?嗯,即使做一些简单的 1 加 1 的事情也会出错。让我想想。
工作
任务是探索将两个数字放在一起的不同方法(见图 3-7 )。
图 3-7
把数字放在一起
解决办法
代码如下:
static void Main(string[] args)
{
// Pay special attention when mixing texts with numbers!
Console.WriteLine(
@"Senior math test
==================
One and one is:");
Console.WriteLine("a) " + 1 + 1);
Console.WriteLine("b) " + (1 + 1));
Console.WriteLine("c) " + "mostly fun");
// Waiting for Enter
Console.ReadLine();
}
讨论
当您将数字与文本混合使用时,结果可能会与您预期的不同!
让我们考虑第一个答案(a)。计算机从左到右计算整个表达式。首先,它接受文本a)
和一个数字(第一个 1)。它将它们连接在一起成为a) 1
。然后,它获取这个新文本和最后一个数字(第二个 1),并再次将它们连接在一起以获得文本a) 11
。
第二个答案(b)不一样。圆括号使计算机首先执行数字的加法,然后才加入左边的文字。
有时,预先计算中间结果并将它们存储在变量中可能更透明。这是你下一章要研究的内容。当然,正如你将要看到的,变量有更多的用途。
摘要
在这一章中,您探索了Console.WriteLine
语句为不同类型的输出提供的几种可能性。具体来说,您已经了解了以下内容:
-
除了文本,您还可以在程序中使用数字。与文本不同,数字不用引号括起来。
-
您可以将几个值组合成表达式。为此,您可以使用诸如
+
、-
和*
这样的操作符。对于数字,他们做普通的算术。加号运算符也适用于文本,在这种情况下,它将两段文本连接成一段。 -
在计算中,你必须时刻注意计算结果的顺序。乘法和除法优先于加法和减法。若要强制不同的评估顺序,请使用括号。
-
引号或换行符等特殊字符使用以反斜杠开头的转义序列输出。
-
通过在多行文本前添加 at (
@
)符号,可以方便地输出预格式化的多行文本。
四、使用变量
在这一章中,你将学习所有关于变量的知识。一个变量是计算机内存中一个程序可以存储东西的指定位置。可以是你想要的任何东西。事实上,你可以根据需要在你的程序中设置任意多的变量。
本章将从一些简单的例子开始,但最终你会发现变量对编程来说是绝对重要的。
存储文本
第一项任务将向您介绍变量。您将学习如何使用它们执行一些基本操作。
工作
您将创建一个名为message
的变量。之后,您将在其中存储一些文本。最后,您将向用户显示变量的值。
解决办法
代码如下:
static void Main(string[] args)
{
// Declaration of a variable to store text
string message;
// Storing a value in prepared variable (assignment statement)
message = "I can't live with you.";
// Another variable (initialized with some value)
string anotherMessage = "I can't live without you.";
// Output of variables
Console.WriteLine(message);
Console.WriteLine(anotherMessage);
// Waiting for Enter
Console.ReadLine();
}
讨论
现在我们来讨论解决方案。
变量声明
如果要使用一个变量,需要先声明(创建)它。
变量声明语句的一般语法如下:
类型名称【空间】变量名称【半结肠】。
在这种情况下,它的内容如下:
string message;
类型表示您想要存储在变量中的值的类别。在这种情况下,您希望存储文本,这就是您使用名为string
的类型的原因。
供选择的
还有一种方法可以编写变量声明语句。在分号前面,可以用等号和变量的初始值。
以下是该语法的一个示例:
string anotherMessage = "I can't live without you.";
赋值语句
代码中还有一点需要解释。第二个声明如下:
message = "I can't live with you.";
这存储了一个值(文本“我不能和你一起生活。”)在预备变量(message
)中,它被称为赋值语句。当你想存放东西的时候,你可以用它。
赋值语句的一般语法如下:
- WHERE(TO STORE)= WHAT(TO STORE);
存储数字
在下一个任务中,您将学习存储数字而不是文本的变量。
工作
您将创建(声明)一个名为number
的变量。之后,你会在里面储存一些数字。最后,您将向用户显示变量的值。
解决办法
数值的数据类型称为int
。严格地说,这是用于整数数(整数)的数据类型。不久你就会明白区分整数和小数在编程中的重要性。
static void Main(string[] args)
{
// Variable for storing number (with initial value)
int number = -12;
// Output of value of the variable
Console.WriteLine("Value of the variable: " + number);
// Waiting for Enter
Console.ReadLine();
}
不要忘记,输入的数字不带引号。
将 1 和 1 相加
什么事?又把 1 和 1 相加?你可能认为我要疯了!
工作
在前一章中,我告诉过你,当把数字和文本结合起来时,变量可以给你提供更大的确定性。现在我回到这个建议。
解决办法
代码如下:
static void Main(string[] args)
{
// Precalculation of result (into a variable)
int sum = 1 + 1;
// Output to the user
Console.WriteLine(
@"Answer to Senior math test
=========================
One and one is: " + sum);
// Waiting for Enter
Console.ReadLine();
}
}
程序运行结果见图 4-1 。
图 4-1
1 加 1 计划的结果
讨论
请将 1 加 1 的计算与上一章的计算进行比较。这里,您将结果显式存储在一个变量中。这可以让你避免可能出现的评估顺序问题和得到 11 的错误答案。
使用变量进行计算
在下一个任务中,您将学习如何同时使用几个变量。
工作
你将在两个变量中存储一些数字。之后你会把他们的和算进第三个。
解决办法
代码如下:
static void Main(string[] args)
{
// 1\. SOLUTION
// Values to be summed
int firstNumber = 42;
int secondNumber = 11;
// Calculating
int sum = firstNumber + secondNumber;
// Output
Console.WriteLine("Sum is: " + sum);
// 2\. SOLUTION
// Declaring all variables at once
int thirdNumber, fourthNumber, newSum;
// Values to be summed
thirdNumber = 42;
fourthNumber = 11;
// Calculating
newSum = thirdNumber + fourthNumber;
// Output
Console.WriteLine("Calculated another way: " + newSum);
// Waiting for Enter
Console.ReadLine();
}
讨论
两个(备选)解决方案显示了您经常会遇到的两种情况:
-
你声明一个变量,然后立即在其中存储一个值。
-
你首先声明一个变量,然后在这个变量中存储一个值。
组装一个大组合
通常,您需要将几个值组合成输出。在本任务中,您将学习如何操作。
工作
我将通过一个足球比赛结果的例子向您展示如何组装复杂的文本(图 4-2 )。
图 4-2
大组合计划
在本例中,您有一些固定文本、一些(潜在的)可变文本和一些(潜在的)可变数字。这是典型的现实情况。
解决办法
要存储(潜在的)变量值,可以使用变量。当然,这些值在这个简单的程序中实际上是固定的,但是通常您会从其他地方获得它们(比如用户、文件、数据库或 web 服务)。你将在本书的后面学习如何从用户那里获得输入。
static void Main(string[] args)
{
// Data in variables
string club1 = "FC Liverpool";
string club2 = "Manchester United";
int goals1 = 3;
int goals2 = 2;
// Output of match result
Console.WriteLine(
"Match " + club1 + " - " + club2 +
" ended with result " +
goals1 + ":" + goals2 + ".");
// Waiting for Enter
Console.ReadLine();
}
讨论
在解决方案中,您应该特别注意以下几点:
-
您使用不同数据类型的变量来存储不同种类的值。
-
您正在从由八个加号连接在一起的九个部分构建显示的消息。信息的某些部分是固定的,而其他部分是可变的。
使用十进制数字
在编程中,你需要彻底区分整数和小数。你已经知道如何处理整数,所以现在你将看到小数。
工作
在这项任务中,我将向您展示一些如何处理小数的示例。
解决办法
在 C# 中,对于十进制数有一种叫做double
的类型。代码如下:
static void Main(string[] args)
{
// IN CODE, decimal separator is always DOT regardless of computer language settings
double piApproximately = 3.14;
// Pi is already available in C#
double piMorePrecisely = Math.PI;
// Decimal numbers have always limited precision
double notCompletelyOne = 0.999999999999999999;
// Outputs
Console.WriteLine("Pi value from our code: " + piApproximately);
Console.WriteLine("Pi value from C#: " + piMorePrecisely);
Console.WriteLine("This should not be exact one: " + notCompletelyOne);
// Waiting for Enter
Console.ReadLine();
}
讨论
请注意以下几点:
图 4-3
十进制数字程序的结果
-
在代码中,您总是需要使用小数点作为数字的整数和小数部分之间的分隔符。
-
但是,输出取决于您的 Windows 设置。正如你在图 4-3 中看到的,我电脑上的输出使用逗号作为小数点分隔符,因为我的电脑设置为捷克语。
-
你也可以看到十进制数没有无限的精度。它们在大约 15 个有效数字后四舍五入。
使用逻辑值
在编程中,你经常会用到逻辑值,也就是“是”和“否”的值。
工作
在这项任务中,我将向您展示如何使用逻辑值。
解决办法
在 C# 中,逻辑值的类型称为bool
。值“是”写成true
,值“否”写成false
。下面是代码:
static void Main(string[] args)
{
// Two logical (Boolean) variables
bool thePrettiestGirlLovesMe = true;
bool iAmHungry = false;
// Use exclamation mark to negate logical value
bool iAmNotHungry = !iAmHungry;
// Output
Console.WriteLine("She loves me: " + thePrettiestGirlLovesMe);
Console.WriteLine("I am hungry: " + iAmHungry);
Console.WriteLine("I am not hungry: " + iAmNotHungry);
// Waiting for Enter
Console.ReadLine();
}
讨论
请注意,每当您需要否定一个逻辑值时(将它从“是”翻转到“否”,然后再翻转回来),您都会使用感叹号。
摘要
在这一章中,你已经了解了变量的重要概念。在每一个真实的程序中,你都需要临时存储值(计算结果、用户输入等。)在计算机的内存中,这正是你使用变量的目的。变量是内存中的一个位置,它有一个引用它的名称和它的数据类型,以明确你将在其中存储什么类型的数据。
具体来说,您学到了以下内容:
-
在使用变量之前,必须先声明它。合适的说法是
string message;
。 -
要在变量中存储一个值,可以使用赋值语句格式where = what;。比如
message = "Some text";
。 -
在 C# 中,文本的数据类型是
string
。 -
整数的数据类型是
int
。 -
在编程中,与通常的用法相反,必须注意区分整数和小数。
-
十进制数的数据类型是
double
。 -
有一种称为
bool
的特殊数据类型,用于存储所谓的逻辑值true
和false
,它们在计算机上相当于“是”和“否”
五、使用对象
类型为string
、int
、double
和bool
的变量总是包含一个值——文本、一个数字或一个是/否值。然而,这样的“原子”值可以被分组到称为对象的集合中。单个对象可以包含多个值,这些值被称为其组件或成员。例如,分组可以发展到一个对象内部可以包含几个其他对象。在这一章中,你将学习关于物体的知识。
现在几点了?
您将遇到的第一个对象是一个DateTime
对象,它包含单个时间实例的各种组件,比如日、月、年、小时、分钟、秒等等。
工作
您将编写一个向用户显示当前日期和时间的程序(参见图 5-1 )。
图 5-1
显示当前日期和时间
在这个任务中,你将了解DateTime
类型的物体。
解决办法
代码如下:
static void Main(string[] args)
{
// Variable of DateTime type, at first empty
DateTime now;
// Storing of current date and time into our variable
now = DateTime.Now;
// Output
Console.WriteLine("Now is " + now);
// Waiting for Enter
Console.ReadLine();
}
今天是几号?
让我们进一步研究一下DateTime
对象。
工作
假设您只对今天的日期感兴趣,不包括时间部分(见图 5-2 )。
图 5-2
仅显示日期
在许多程序中,今天的日期和当前的时间相差很大!
解决办法
代码如下:
static void Main(string[] args)
{
// Variable of DateTime type, at first empty
DateTime today;
// Storing of today's date (without time component)
today = DateTime.Today;
// Output
Console.WriteLine("Today is " + today);
// Waiting for Enter
Console.ReadLine();
}
使用日期组件
你可能想知道提到的对象的组件在哪里。让我们看看DateTime
对象的组件。如果将一个DateTime
类型的变量附加一个点,Visual Studio IntelliSense 会显示所有可能的可用组件。
工作
您将了解到DateTime
对象的各种组件。
解决办法
代码如下:
static void Main(string[] args)
{
// Current date and time (using single statement)
DateTime now = DateTime.Now;
// Picking up individual components
int day = now.Day;
int month = now.Month;
int year = now.Year;
int hours = now.Hour;
int minutes = now.Minute;
int seconds = now.Second;
DateTime justDateWithoutTime = now.Date;
// Output
Console.WriteLine("Day: " + day);
Console.WriteLine("Month: " + month);
Console.WriteLine("Year: " + year);
Console.WriteLine("Hours: " + hours);
Console.WriteLine("Minutes: " + minutes);
Console.WriteLine("Seconds: " + seconds);
Console.WriteLine("Date component: " + justDateWithoutTime);
// Formatting output our way
Console.WriteLine("Our output: " +
year + ", " + month + "/" + day +
" " +
hours + " hours " + minutes + " minutes");
// Waiting for Enter
Console.ReadLine();
}
图 5-3 显示了DateTime
物体的组成部分。
图 5-3
日期时间对象的组件
使用名称空间
好了,现在你已经见到了你的第一个对象,我应该告诉你一些关于名称空间的事情。
重要用途
在最后一个项目仍然打开的情况下,使用两个斜杠注释掉Program.cs
源代码中的第一行(using System;
)(参见图 5-4 )。您也可以删除该行。然而,要回到最初的版本,更方便的是只注释掉这一行。
图 5-4
注释掉第一行
一瞬间,源代码中出现了大量的红色波浪。当您尝试使用 F5 键启动您的程序时,它将无法启动(参见图 5-5 )。
图 5-5
获取错误
提醒您一下,在出现的错误对话框中,总是单击“否”。
出现的错误列表窗格显示了大量错误——突然,Visual Studio“不知道”任何一个DateTime
或Console
(参见图 5-6 )。
图 5-6
错误列表窗格
using
线挺重要的吧?接下来我会解释原因。
名称空间
C# 中的几乎所有东西都属于某个更高层次的单元。在这种情况下,DateTime
和Console
都属于System
名称空间。如果您想使用它们,您必须在源代码的顶部用一行using
声明相应的名称空间。否则,Visual Studio 不理解它们。
为什么会有名称空间这样的东西?你要它们做什么?嗯,对象的名字并不是无限的,所以你需要指定你使用的是哪一个。例如,你不需要使用微软的DateTime
类;你可以编写你自己的DateTime
,或者你可以从另一个程序员那里购买一些美妙的DateTime
。这就是为什么你需要一种方法来区分它们。这种方式是通过命名空间。
每个对象类型都属于某个名称空间。例如,System
名称空间是由微软“管理”的。如果我准备了自己的DateTime
,我可能会把它放在RadekVystaveˇl.Books
名称空间中。
好吧,也许没人需要自己做DateTime
,但是还有更好的例子。例如,为具有图形用户界面的程序中的文本框控件准备的TextBox
类存在于微软的至少四个版本中:
-
对于 Windows 窗体技术中的桌面应用
-
对于 WPF 科技的桌面应用
-
对于 web 应用
-
对于所谓的通用(面向触摸)应用
提到的每个文本框都属于一个单独的名称空间。
不使用
如果你现在删除你用来注释掉using System
;
行的两个斜线,一切都会恢复到正常状态。然而,看看没有using
的程序会是什么样子可能会很有趣,这也是你接下来要做的。
在您的源代码中,您需要用适当的名称空间,即System
,用限定DateTime
和Console
的所有出现的。从技术上讲,限定是通过在被限定的名称前面加上名称空间来执行的。
//using System;
namespace Date_components__without_using_
{
class Program
{
static void Main(string[] args)
{
// Current date and time (using single statement)
System.DateTime now = System.DateTime.Now;
// Picking up individual components
int day = now.Day;
int month = now.Month;
int year = now.Year;
int hours = now.Hour;
int minutes = now.Minute;
int seconds = now.Second;
System.DateTime justDateWithoutTime = now.Date;
// Output
System.Console.WriteLine("Day: " + day);
System.Console.WriteLine("Month: " + month);
System.Console.WriteLine("Year: " + year);
System.Console.WriteLine("Hours: " + hours);
System.Console.WriteLine("Minutes: " + minutes);
System.Console.WriteLine("Seconds: " + seconds);
System.Console.WriteLine("Date component: " + justDateWithoutTime);
// Formatting output our way
System.Console.WriteLine("Our output: " +
year + ", " + month + "/" + day +
" " +
hours + " hours " + minutes + " minutes");
// Waiting for Enter
System.Console.ReadLine();
}
}
}
用using
s 更好,不是吗?
C# 9.0 极简程序
因为我们正在试验Main
方法之外的东西,所以现在是了解 C# 9.0 创新的适当时机,它允许您省略“样板代码”,即namespace
、class
和Main
行(当然,加上相应的括号)。
尽快回到本章中的“使用日期组件”,并再次在 Visual Studio 中打开适当的项目。
除了using
行之外,删除所有不属于我们代码的内容。具体来说,您应该删除以namespace
、class
和Main
开头的三行,加上三个左括号和三个右括号。您在 Visual Studio 中的代码编辑器将如图 5-7 所示。
图 5-7
省略“样板代码”
按 F5 键运行程序。起初,删除所有这些行似乎不是一个好主意(见图 5-8 )。
图 5-8
Visual Studio 抱怨 C# 版本
IDE 抱怨 C# 版本,至少在我用 Visual Studio 预览版的电脑上是这样。错误信息说我们需要 C# 9.0。因此,如果我们设法切换到 C# 9.0,我们的案例最终可能不会失败。
从 Visual Studio 菜单中,选择项目➤属性(参见图 5-9 )。
图 5-9
选择项目属性菜单
在出现的屏幕中,转到目标框架组合框并选择“”。NET 5.0”(见图 5-10 )。这将打开 C# 9.0。
图 5-10
改变目标
再次按 F5 键,程序现在应该可以顺利启动了。
使用环境对象
作为本章的总结,你将再看一眼你已经知道的Environment
物体。从不同的角度看待事物是富有成效的。
工作
Environment
对象包含关于程序“环境”的信息(例如,关于计算机和操作系统)。您已经看到了Environment.NewLine
组件。现在,您将了解更多组件。
解决办法
代码如下:
static void Main(string[] args)
{
// Displaying components of Environment object
Console.WriteLine("Device name: " + Environment.MachineName);
Console.WriteLine("64-bit system: " + Environment.Is64BitOperatingSystem);
Console.WriteLine("User name: " + Environment.UserName);
// Waiting for Enter
Console.ReadLine();
}
与前面的程序相反,这里我没有将对象组件提取到变量中。我直接使用它们只是为了让你能看到使用它们的另一种可能的方式。
摘要
在这一章中,你已经熟悉了对象,它本质上是几个组件的聚合。与“原子”(单值)类型如int
或string
相反,对象通常包含许多值。
具体来说,您遇到了以下情况:
-
DateTime
对象,可用于检索当前日期或时间 -
Environment
对象,可用于检索程序的“环境”信息,如计算机名或用户名
您还学到了以下内容:
-
对象可以存储在适当类型的变量中。
-
一个对象的组件可以通过所谓的点符号来访问。您写下对象变量的名称并添加点,由于 Visual Studio IntelliSense,可用组件的列表会弹出。
-
每个对象类型都属于某个名称空间。简单地说,名称空间可以被看作是相似对象类型的容器。
-
一个重要的名称空间是
System
名称空间,它包含基本的对象类型,如DateTime
或Console
。 -
您指出您想要使用一个特定的名称空间,在源代码的开头有一个
using
行。 -
如果没有包含适当的
using
行,就必须完全限定类型名。这意味着您要在类型的名称前面加上名称空间的名称和一个点。 -
C# 9.0 允许您省略所谓的“样板”代码,即从项目模板中生成的代码,而不是由您编写的代码。
六、使用对象操作
从上一章你已经知道,一个对象是一种由几个“数据片段”组成的数据集合体您还知道,当您输入对象名称、点号和组件名称时,可以访问对象的单个组件。在这一章中,你会发现编程中的对象甚至更复杂。您将了解到,除了数据组件之外,对象还可以封装您可以使用相应对象执行的操作。通过几个任务,你将练习使用对象动作。
以文本显示月份
第一个任务将向您介绍可以使用DateTime
对象执行的操作。
工作
你将编写一个程序,用文本显示当前日期,而不是用数字(或者,通常是长格式),如图 6-1 所示。
图 6-1
用文本显示当前日期和月份
您可以使用DateTime
对象的ToLongDateString
动作来完成这项任务。
解决办法
代码如下:
static void Main(string[] args)
{
// Today's date
DateTime today = DateTime.Today;
// Output
Console.WriteLine("Today is " + today.ToLongDateString());
// Waiting for Enter
Console.ReadLine();
}
讨论
请注意以下几点:
-
当在 C# 中启动某个对象动作时,动作名称总是被括号(圆括号)所附加,即使它们之间没有任何内容。
-
括号通常不是空的,而是包含一个参数(或多个参数),这是一些特定于动作的信息。例如,在
Console.WriteLine
动作的情况下,您在括号中指定想要显示的内容。 -
您可以对对象执行的操作也被称为方法。
-
ToLongDateString
方法显示的月份名称取决于操作系统的语言设置。
明天展示
除了将日期转换成文本,对象还有更多可用的操作。日期运算尤其重要。
工作
你将编写一个显示明天日期的程序(见图 6-2 )。
图 6-2
显示明天的日期
解决办法
DateTime
对象可以执行更多有趣的动作(方法),例如:
-
使用
AddDays
进行日期运算 -
使用
ToShortDateString
以短格式显示日期
代码如下:
static void Main(string[] args)
{
// Today's date
DateTime today = DateTime.Today;
// Tomorrow's date
DateTime tomorrow = today.AddDays(1);
// Output
Console.WriteLine("Today is " + today.ToShortDateString() + ".");
Console.WriteLine("I will start learning on " + tomorrow.ToShortDateString() + ".");
// Waiting for Enter
Console.ReadLine();
}
显示特定日期
让我们继续讨论日期,看看什么是构造函数。
工作
处理日期时,不必总是从今天的日期开始。你可以选择一些具体的日期(见图 6-3 )。
图 6-3
从特定的日期开始
解决办法
通过调用对象的构造函数,可以创建一个用特定日期初始化的DateTime
对象。您输入new
单词,键入名称(例如DateTime
,并使用括号括起可能的参数。在这种情况下,参数是年、月和日。
static void Main(string[] args)
{
// A specific date
DateTime overlordDday = new DateTime(1944, 6, 6);
// Output
Console.WriteLine("D-Day (Overlord operation): " +
overlordDday.ToLongDateString() + ".");
// Waiting for Enter
Console.ReadLine();
}
滚动单个模具
约会够多了。现在你将学习如何处理偶然性或随机性。
工作
你将编写一个程序,将一个骰子“掷出”三次(见图 6-4 )。
图 6-4
滚动骰子
解决办法
要使用 chance,你需要一个随机数生成器。在 C# 中,您使用Random
对象来实现这个目的。
在程序开始运行时,你首先通过调用其构造函数一次来创建一个Random
对象,然后你重复调用其方法Next
。
static void Main(string[] args)
{
// Creating random number generator object
Random randomNumbers = new Random();
// Repeatedly throwing a die
int number1 = randomNumbers.Next(1, 6 + 1);
int number2 = randomNumbers.Next(1, 6 + 1);
int number3 = randomNumbers.Next(1, 6 + 1);
// Output
Console.WriteLine("Thrown numbers: " +
number1 + ", " +
number2 + ", " +
number3);
// Waiting for Enter
Console.ReadLine();
}
注意
Next
方法(动作)需要括号中的两个参数:
-
生成数区间的下界
-
上界增加 1 (对不起,我不是发明这种陌生感的人)
掷骰子
继续讨论随机数的话题,现在你将看到如何使用多个随机数序列。
工作
你将编写一个程序,将一对骰子掷出三次(见图 6-5 )。我会告诉你正确的方法和错误的方法。
图 6-5
掷骰子三次
解决办法
该解决方案的主要信息是使用单个随机数发生器。如果你几乎同时创建了两个,它们通常会生成相同的数字!代码如下:
static void Main(string[] args)
{
// 1\. CORRECT SOLUTION
// Creating random number generator object
Random randomNumbers = new Random();
// Repeatedly throwing two dice
int correctNumber11 = randomNumbers.Next(1, 6 + 1);
int correctNumber12 = randomNumbers.Next(1, 6 + 1);
int correctNumber21 = randomNumbers.Next(1, 6 + 1);
int correctNumber22 = randomNumbers.Next(1, 6 + 1);
int correctNumber31 = randomNumbers.Next(1, 6 + 1);
int correctNumber32 = randomNumbers.Next(1, 6 + 1);
// Output
Console.WriteLine("CORRECTLY");
Console.WriteLine("Thrown couples: " +
correctNumber11 + "-" + correctNumber12 + ", " +
correctNumber21 + "-" + correctNumber22 + ", " +
correctNumber31 + "-" + correctNumber32);
// 2\. INCORRECT SOLUTION
// Two random number generators
Random randomNumbers1 = new Random();
Random randomNumbers2 = new Random();
// Repeatedly throwing two dice
int incorrectNumber11 = randomNumbers1.Next(1, 6 + 1);
int incorrectNumber12 = randomNumbers2.Next(1, 6 + 1);
int incorrectNumber21 = randomNumbers1.Next(1, 6 + 1);
int incorrectNumber22 = randomNumbers2.Next(1, 6 + 1);
int incorrectNumber31 = randomNumbers1.Next(1, 6 + 1);
int incorrectNumber32 = randomNumbers2.Next(1, 6 + 1);
// Output
Console.WriteLine(); // empty line
Console.WriteLine("INCORRECTLY");
Console.WriteLine("Thrown couples: " +
incorrectNumber11 + "-" + incorrectNumber12 + ", " +
incorrectNumber21 + "-" + incorrectNumber22 + ", " +
incorrectNumber31 + "-" + incorrectNumber32);
// Waiting for Enter
Console.ReadLine();
}
获取桌面的路径
作为本章的结尾,你将学习另一个物体的动作。
工作
当您处理文件时,您可能希望在用户的桌面上创建一个文件。然而,每个人都有自己的桌面文件系统路径。我会告诉你如何找到那条路径(见图 6-6 )。
图 6-6
寻找道路
解决办法
可以用你的老朋友,Environment
对象。代码如下:
static void Main(string[] args)
{
// Finding path to the desktop
string pathToDesktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
// Output
Console.WriteLine("Path to your desktop: " + pathToDesktop);
// Waiting for Enter
Console.ReadLine();
}
列举
要特别注意你对桌面感兴趣的方式。Desktop
的值是被称为Environment.SpecialFolder
的枚举的值之一。
每当 Visual Studio 希望您输入枚举值时,它通常会为您提供相应的枚举。在这种情况下,当您从 IntelliSense 中选择GetFolderPath
并随后键入左括号时,会立即弹出Environment.SpecialFolder
枚举(参见图 6-7 )。
图 6-7
使用智能感知
使用 Tab 键选择提供的枚举,输入一个点,然后选择Desktop
值。
摘要
本章的主要目的是向您展示对象是更复杂的实体,而不仅仅是数据组件的集合体。具体来说,它们通常包含方法,这些方法是您可以执行的操作,通常对对象的数据进行操作。
您已经熟悉了DateTime
、Random
和Environment
对象的各种方法。具体来说,您学习了以下内容:
-
使用
ToLongDateString
和ToShortDateString
方法将日期转换为文本 -
日期运算的方法之一,即
AddDays
-
在指定范围内产生单个随机数的
Next
方法 -
GetFolderPath
方法,可用于获取特殊文件夹的文件系统路径,如Desktop
、Documents
等
您还了解了如何使用构造函数调用来创建对象。您输入了new
单词,后面是对象类型的名称和括号。一些构造函数,比如Random
对象,只需要空括号,而其他的,比如DateTime
,需要你在括号之间指定一些值(年、月、日)。
在最后一个例子中,您还发现了所谓的枚举的用法,它本质上是一组预定义的(枚举的)值。Visual Studio 的 IntelliSense 在处理枚举时非常有用。
七、关于对象的更多信息
您已经看到一个对象充当数据聚集或容器。您已经看到了它所包含的数据作为它的属性,在对象名后面加上一个点就可以访问这些属性。访问一个属性意味着要么质疑它的价值,要么赋予它一个新的价值。
您还发现了(可能很多)动作可以与一个对象相关联。动作被称为方法,和属性一样,它们可以在对象名称后添加一个点来访问。此外,访问一个对象的特定方法需要在方法名中添加一对括号,括号内可能有参数值。访问一个方法(通常你会说调用它)意味着启动它实现的操作并执行它包含在里面的语句(在你不知道的情况下)。
这些是用对象编程的原则,它们是你在前两章中学习的基础。这一章将通过让你更深入地了解事物来充实你的知识。
现在让我们更深入地研究一下对象。
作为对象的文本
在 C# 中,即使是普通的文本也表现得像一个对象;你可以在文本上加一个点,这样就有很多可能性。让我们来看看。
工作
您将创建一个程序,显示文本的多个字符,将文本转换为大写,并检查文本是否包含特定的单词(图 7-1 )。
图 7-1
最终方案
解决办法
代码如下:
static void Main(string[] args)
{
// Some text to try things on
string text = "This is the last day of our acquaintance";
// What e.g. can be done with texts
Console.WriteLine("Original text: " + text);
Console.WriteLine("Number of characters: " + text.Length);
Console.WriteLine("In uppercase: " + text.ToUpper());
Console.WriteLine("Does it contain word \"last\"? " + text.Contains("last"));
// Waiting for Enter
Console.ReadLine();
}
讨论
数据成员(如Length
)没有括号,与方法(如ToUpper
、Contains
)相反,即使它们之间没有任何东西,也总是需要括号。
如何快速发现某个东西是否是方法(因此需要括号)?您可以通过查看智能感知中的紫色立方体或在工具提示中查找括号来完成此操作(参见图 7-2 )。
图 7-2
检查某个东西是否是一个方法
作为对象的数字
在前面的练习中,您看到了普通文本——一个类型为string
的值——可以表现得像一个对象,并显示内部组件,如属性和方法。现在你会看到偶数可以表现得像物体一样,尽管它们的行为要稀疏得多。其实唯一值得一提的是转换成文本的动作。
工作
您将探索在一个数字变量上附加一个点后会弹出什么,并且您将学习如何将数字转换成文本。
解决办法
要将一个数字转换成它的文本表示,使用ToString
方法。实际上,要将的任何东西转换成文本,C# 中总有可用的ToString
方法(action)。
static void Main(string[] args)
{
// Some number
int number = 1234;
// Conversion to text
//string numberAsText = number; // DOES NOT WORK!
string numberAsText = number.ToString();
// Output
Console.WriteLine("Output of number: " + number);
Console.WriteLine("Output of text: " + numberAsText);
// Waiting for Enter
Console.ReadLine();
}
讨论
您可以看到类型为int
的值不能直接赋给类型为string
的变量。你得先把它转换成文本形式。
当然,在输出中,你看不到任何区别(见图 7-3 )。
图 7-3
输出
然而,很多时候你需要将一个数字转换成文本,而不是立即显示出来。然后,您将把值的文本形式存储在一个string
类型的变量中,这就是您刚才看到的。
作为讨论的总结,我将告诉你为什么你看不到图 7-3 的两条线有任何不同:
-
Console.WriteLine
方法将获得的所有内容转换成文本。它在幕后使用ToString
转换来实现这一点。 -
如果您使用加号将一些文本与一个数字连接起来,该数字会自动转换为 C# 中的文本。如果你想要更大的控制力,总是写下与数字相关的
.ToString()
。
格式化数字
在上一个练习中,您忙于将数字转换成文本表示。然而,单个数字可以通过多种方式以文本形式表示。您现在将学习小数位数、舍入、千位分隔等等。
工作
在本练习中,你将看到几个使用ToString
方法获得格式良好的数字输出的例子(见图 7-4 )。
图 7-4
格式良好的输出
解决办法
代码如下:
static void Main(string[] args)
{
// Some money amounts and a number
double amount = 1234.56;
double anotherAmount = 789;
int wholeNumber = 1234567;
// Formatted outputs
Console.WriteLine("Separating thousands and millions + money to cents");
Console.WriteLine(amount.ToString("N2"));
Console.WriteLine(anotherAmount.ToString("N2"));
Console.WriteLine(wholeNumber.ToString("N0"));
// Waiting for Enter
Console.ReadLine();
}
与前面的练习相反,ToString
方法调用现在在圆括号之间有一个参数。格式字符串指定了输出的样子。
在这里使用的格式字符串中,N
表示需要千位分隔,二和零表示输出中的小数位数。
本地化输出
普通的数字格式(如前一个任务)根据 Windows 语言设置工作。但是,有时您不希望输出依赖于用户设置。您可能想要一个固定的语言设置,如美国、捷克或其他语言。
工作
在本练习中,您将学习两种不同语言风格的数字显示,捷克语和美语(见图 7-5 )。
图 7-5
两种不同的数字样式
如您所见,在捷克语中,您使用空格作为千位分隔符,使用逗号作为小数点分隔符。同样的逗号在美国格式中被用作千位分隔符,所以你可以想象让计算机决定使用什么语言(根据 Windows 设置)有时会导致混乱和不正确的程序行为。
解决办法
首先,在源代码顶部添加适当的using
行(引用System.Globalization
名称空间),如图 7-6 所示。
图 7-6
添加使用行
之后,像往常一样将代码输入到Main
方法中:
static void Main(string[] args)
{
// Whole and decimal number
int wholeNumber = 1234567;
double decimalNumber = 1234567.89;
// Localization objects
CultureInfo czech = new CultureInfo("cs-CZ");
CultureInfo american = new CultureInfo("en-US");
// Localized output
Console.WriteLine("Whole number - Czech: " + wholeNumber.ToString("N0", czech));
Console.WriteLine("Whole number - American: " + wholeNumber.ToString("N0", american));
Console.WriteLine("Decimal number - Czech: " + decimalNumber.ToString("N2", czech));
Console.WriteLine("Decimal number - American: " + decimalNumber.ToString("N2", american));
// Waiting for Enter
Console.ReadLine();
}
结束语
为了在本书的范围内完成您对对象的了解,我将向您介绍更多的对象概念。如果你现在还不能完全理解它们,请不要担心。在你学习的这个阶段,仅仅了解他们是可以的。
静态对象
首先,我想让你们注意两种物体的存在。有DateTime
、Random
、CultureInfo
等“经典”对象,也有Console
、Environment
、Math
等“静态”对象。
你可以在你的程序中拥有任意多的经典对象。例如,变量today
和tomorrow
中有两个DateTime
。变量randomNumbers
、randomNumbers1
和randomNumbers2
中也有三个Random
。
与经典对象相反,静态对象总是单一的——你只有一个Console
,一个Environment
,还有一个Math
。
此外,您总是按需创建经典对象,而静态对象在程序启动时就已经存在,无需您付出任何努力。
严格使用官方术语,我应该谈论“具有静态组件的类”而不是“静态对象”然而,我更喜欢后者,初学者友好的术语。近似美丽比完全丑陋要好。
班级
每一份关于物体的文件或教科书都大量使用了类这个词。那么,这意味着什么呢?简单地说,类是对象数据类型的同义词。你可以说“一个Random
类的对象”,而不是“一个Random
类型的对象”这意味着一个类也可以被看作是某一类对象的名字。
类和对象之间的关系
从另一个角度来看,类也是一个 C# 源代码,它定义了一个特定类型的对象包含什么以及它的行为方式。你也可以说类是对象的模板。比如Random
类源代码(微软有,你没有)定义了所有 Random
会有什么属性和什么方法。
因此,所有的Random
对象都以同样的方式运行,因为它们都是从同一个模板或同一个类中创建的。所有的DateTime
和所有的CultureInfo
也是如此,以此类推。
换句话说,作为一个众所周知的面向对象编程准则,对象是一个类实例。单词 instance 表示一次实现或一次事件。
特殊班级
在本章中,您看到了文本、数字等也像对象一样。以下是它们对应的类:
|数据类型
|
相应的类别
|
| — | — |
| string
| String
|
| int
| Int32
|
| double
| Double
|
| bool
| Boolean
|
| ...
| ...
|
在 C# 中,可以交替使用string
和String
、int
和Int32
等等。当然,您需要在源代码的顶部有一个using System;
行,因为所有相应的类都属于那个特定的名称空间。
结构
在 C# 中,你也可能会遇到术语结构或结构。什么是结构?
你可以把它们看作轻量级的类。在初学者的水平上,它们几乎与正常的类没有什么区别,所以你可能会在你长时间看到结构或结构的地方简单地替换掉类这个词。
例如,DateTime
是一个结构的主要例子。然而,为了简单起见,在本书的每一处,我都将DateTime
与普通的类如Random
或CultureInfo
同等对待。当你在本书的层次上工作时,你可能察觉到的唯一微妙的区别是DateTime
对象不一定要被显式地创建,例如,通过一个构造函数调用。声明该类型的变量就足够了,尽管可能不实用。
摘要
在本章中,您学习了即使是普通的文本和数字也可以像对象一样工作。具体来说,您学习了以下内容:
-
Length
属性,加上文本/字符串的ToUpper
和Contains
方法 -
ToString
数字法
在后一种情况下,您还看到了由ToString
方法生成的输出可以由格式字符串控制(如N2
等)。)和语言规范(CultureInfo
宾语)。将来,你会发现在 C# 中使用ToString
方法绝对方便,不仅仅是数字。
您已经初步了解了对象编程术语。具体来说,请注意以下几点:
-
与普通对象相反,静态对象总是存在于单个副本中。尽管你可以拥有尽可能多的
DateTime
,但你永远只有一个Console
。 -
单词 class 是“对象数据类型”的同义词你会经常读到特定类的对象,这意味着“特定类型的对象”