0 写在前面

参考书目

  • Microsoft Visual C#: An Introduction to Object-Oriented Programming
  • Starting Out with Visual C#

2026/07/06
目前在看第一本书,所以笔记内容基本都是第一本书上的内容,差不多一个晚上看到第二章开头,这书写得真不错

1 A First Program Using C#

1.1 The Programming Proess

Each programming language is a system of
special words and grammar that you can use to write statements to direct computer operations.

A computer program is a set of instructions that tells a computer what to do. Programs are also
called software; software comes in two broad categories:

  1. System software describes the programs that operate the computer. Examples include operating systems such as Microsoft Windows, macOS, and Linux.
  2. Application software describes the programs that allow users to complete tasks such as creating documents, calculating paychecks, and playing games. (Application software programs are often called apps.)

The physical devices that make up a computer system are called hardware. Internally, computer hardware is constructed from circuitry(电路) that consists of small on/off switches; the most basic circuitry-level software that computers use to control the operation of those switches is called machine language. Machine language is expressed as a series of 1s and 0s—1s represent switches that are on, and 0s represent switches that are off.

Programming has become easier because of the development of high-level programming
languages. A high-level programming language allows you to use a limited vocabulary of reasonable keywords. Keywords are identifiers that have special meaning in a language.
Each high-level language has its own syntax, or rules of the language.

The program statements you write in a high-level language are source code. (Source code is often said to be stored in a source file.) Programmers use a computer program called a compiler to translate their high-level source code statements (in other words, compile them) into machine code (machine
language).
The compiler issues an error message each time a programmer commits a syntax error—
that is, each time the programmer uses the language incorrectly.

1.2 Procedural and Object-Oriented Programming

When you write a procedural program, you use your knowledge about a programming language to create and name computer memory locations that can hold values, and you write a series of steps or operations to manipulate those values.

a = 2
Each named computer memory location that can hold data is a variable—so named because it holds a value that might vary. The memory location referenced by the name a might contain different values.

For convenience, the individual operations used in a procedural program often are grouped into logical units; each of these units is a method.

A procedural program divides a problem’s solution into multiple methods, each with a unique name.
A program can then call or invoke any method that might, as examples, input, manipulate, or output one
or more values stored in variables.

这里用的method好像是OOP的术语,特指绑定在某个类/对象上的函数

哈哈,关于这个术语我还问了AI,以为是教科书的笔误/安排,没想到后面就读到了解释
Depending on the programming language, a method is sometimes called a procedure, subroutine, or function. In C#, the preferred term is method.

Object-oriented programming (OOP) is an extension of procedural programming. OOP uses variables and methods like procedural programs do, but it focuses on objects that contain the variables and methods. An object is a concrete entity(实体) that has attributes and behaviors:

  1. The attributes of an object are the features it “has”; the state of an object describes the values of all of its attributes. For example, attributes of a paycheck include its payee(付款人) and monetary value, and the state of those attributes for one object might be Fatima Masood and €800. The state of the attributes can be different for a different object.
  2. The behaviors of an object are the things it “does,” or its methods; for example, a paycheck object can be written and cashed, and it contains a method to calculate the check amount.

1.3 Features of Object-Oriented Programming Languages

For a language to be considered object oriented, it must support the following features:

  • Classes
  • Objects
  • Encapsulation and interfaces
  • Inheritance
  • Polymorphism

A class describes potential objects, including their attributes and behaviors. A class is similar to a recipe or a blueprint in that it describes what features objects will have and what they will be able to do after they are created. An object is an instance of a class; it is one tangible(有形的,实际的) example of a class.

Suppose that you create a class named Automobile(汽车). Some of an Automobile’s attributes are its make, model, year, and purchase price. All Automobiles possess the same attributes, but not the same values, or states, for those attributes. (Programmers also call the values of an object’s attributes the properties of the object.) When you create specific Automobile objects, each object can hold unique values for the attributes, such as Toyota Camry, 2025, and $42,000. Similarly, a Dog has attributes that include its breed, name, age, and vaccination status; the attributes for a particular dog might be Labrador retriever, Murphy, 7, and current.

An object belongs to a specific class. If your friend purchases an Automobile, you know it has a model name; if your friend gets a Dog, you know it has a breed. You probably don’t know the current state of the Automobile’s speed or of the Dog’s shots, but you do know that those attributes exist for the Automobile and Dog classes.

使用C#时,命名类一般用一个首字母大写的名词,如果这个名字不少于两个单词,使用驼峰命名,如BankAccount

Besides attributes, objects possess methods that they use to accomplish tasks, including changing attributes and discovering the values of attributes.

Each Automobile has a method for moving forward and backward. Each Automobile also can be filled with gasoline or be washed; both are methods that change some of an Automobile’s attributes. Methods also exist for determining the status of certain attributes, such as the current speed of an Automobile and the number of gallons of gas in its tank.

Like procedural programs, object-oriented programs have variables (attributes) and procedures (methods), but the attributes and methods are encapsulated(封装) into objects.

Encapsulation is the technique of packaging an object’s attributes and methods into a cohesive unit that can be used as an undivided entity. Programmers sometimes refer to encapsulation as using a black box, a device you use without regard for the internal mechanisms. If an object’s methods are well written, the user is unaware of the low-level details about how the methods are executed; in such a case, the user must understand only the interface or interaction between the method and object.

For example, if you can fill your Automobile with gasoline, it is because you understand the interface between the gas pump nozzle(喷嘴) and the vehicle’s gas tank opening. You don’t need to understand how the pump works or where the gas tank is located inside your vehicle.

Object-oriented programming languages support two other distinguishing features in addition to organizing objects as members of classes:

  1. Inheritance provides the ability to extend a class to create a more specific class. The more specific class contains all the attributes and methods of the more general class and usually contains new attributes or methods as well. (例如,我们已经创建了一个叫乐器的类,我们可以再创建一个叫钢琴的类,它继承乐器类的所有attributes和methods,还会多出一些methods或者attributes,比如黑键数量(attribute),延长声音(method))
  2. Polymorphism(多态) is the ability to create methods that act appropriately depending on the context.
    That is, programs written in object-oriented languages can distinguish between methods with the same name based on the type of object that uses them. You are able to “fill” both a Dog and an Automobile, but you do so by very different means. Similarly, the procedure to “fill” a ShowDog might require different food than that for a “plain” Dog.
    Older, non-object-oriented languages could not make such distinctions, but object-oriented languages can.

1.4 The C# Programming Language

The C# programming language was developed as an object-oriented and component-oriented language. It
is part of Microsoft Visual Studio, a package designed for developing applications that run on Windows
computers.
Unlike other programming languages, C# allows every piece of data to be treated as an object and to consistently employ the principles of object-oriented programming.

1.5 Writing a C# Program that Produces Output

1
2
3
4
5
6
7
class FirstClass
{
static void Main()
{
System.Console.WriteLine("Hello, world !");
}
}

The statement System.Console.WriteLine("Hello, world !"); has the following features:

  1. The statement ends with a semicolon because all C# statements do.
  2. The text “Hello, world !” is a literal string of characters—that is, a series of characters that will be used exactly as entered. Any literal string in C# appears
    between double quotation marks.
  3. The string “Hello, world !” appears within parentheses because the string is an argument to a method, and arguments to methods always appear within parentheses.
    An argument represents information that a method needs to perform its task. In this case, the method’s name is WriteLine(), or, more completely, System.Console.WriteLine()

WriteLine()和Write()的区别在于前者会换行
The Console class was created and endowed(赋予) with the method named WriteLine(). When you use the WriteLine() method, programmers say that you call it or invoke it.

在System.Console.WriteLine("Hello, world !");中,System是一个namespace

A namespace is a construct that acts like a container to provide a way to group similar classes. To organize your classes, you can (and will) create your own namespaces. The System namespace, which is built into your C# compiler, holds commonly used classes.

The dots in System.Console.WriteLine("Hello, world !"); are used to separate the names of the namespace, class, and method.

Every executable C# application must contain a Main() method because that is the starting point for every program. You also will create classes that are not programs, and so do not need a Main() method. For example, a Dog or Automobile class would not usually be a program. Rather, they would be classes from which objects are created, and, in turn, those objects would be used in programs with a Main() method.

In the method header static void Main(), the keyword static indicates that the Main() method will be executed through a class —— not by a variety of objects. It means that you do not need to create an object of type FirstClass to use the Main() method defined within
FirstClass(带static的method不依赖于对象,不需要创建对象就能直接运行).
When the keyword void is used in the Main() method header, it does not indicate that the method does not return any value when called.

The name of the method is Main(). A class that contains a Main() method is an application class. Applications are executable or runnable. A class that does not contain a Main() method is a non-application class and is not runnable. Non-application classes provide support for other classes

1.6 Selecting Identifiers

Every method that you use within a C# program must be part of a class. To create a class, you use a class header and curly braces in much the same way you use a header and braces for a method within a class.

In C#, an identifier must begin with an underscore, the @ sign, or a letter, and it can contain only letters, digits, underscores, and the @ sign.

1.7 Adding Comments to a Program

就是//和/**/

1.8 Using the System Namespace

You use a namespace with a using clause, or using directive, to shorten statements when you need to repeatedly use a class from the same namespace.

1
2
3
4
5
6
7
8
9
class ThreeLinesOutput
{
static void Main()
{
System.Console.WriteLine("Line One");
System.Console.WriteLine("Line Two");
System.Console.WriteLine("Line Three");
}
}
1
2
3
4
5
6
7
8
9
10
using System;
class ThreeLineOutput
{
static void Main()
{
Console.WriteLine("Line One");
Console.WriteLine("Line Two");
Console.WriteLine("Line Three");
}
}

You can now reduce typing in programs even further by including the namespace and the class for WriteLine() at the top of the program. When you write using static System.Console; at the top of a program. Recall that static means a method is used without creating an object.

1
2
3
4
5
6
7
8
9
10
using static System.Console;
class ThreeLineOutput
{
static void Main()
{
WriteLine("Line One");
WriteLine("Line Two");
WriteLine("Line Three");
}
}

1.9 Compiling and Executing a C# Program from the Command Line

后面是实操部分,先鸽(

2 Using Data

2.1 Declaring Variables

A data item is constant when it cannot be changed after a program is compiled.
For example, if you use the number 347 within a C# program, then 347 is a constant, and every time you execute the program, the value 347 will be used. You can refer to the number 347 as a literal constant because its value is taken literally at each use.

On the other hand, when you want a data item’s value to be able to change, you can create a variable. A variable is a named location in computer memory that can hold different values at different points in time.
Different values might be used when the program is executed multiple times, or different values might be used at different times during a single program execution.

Whether it is a constant or a variable, each data item you use in a C# program has a data type. A data type describes the format and size of a data item and defines what types of operations can be performed with the item. (The size of a data item refers to the amount of memory it occupies.)

C# provides for 15 basic or intrinsic types of data, the ones most commonly used are int, double, decimal, char, string, and bool. Each C# intrinsic type is an alias(别名), or other name, for a class in the System namespace. All of the built-in types except object and string are called simple types.

By convention, each C# variable name starts with a lowercase letter and uses camel casing if it contains multiple words.

A variable declaration is the statement that names a variable and reserves storage for it.

1
2
3
4
5
6
7
8
9
10
int myAge = 25;

/*You can use the full name*/
System.Int32 myAge = 25;

/*Declare multiple variables of the same type*/
int myAge = 25, yourAge = 19;

int myAge = 25,
yourAge = 19;

2.2 Displaying Variable Values

1
2
3
4
5
6
7
8
9
using static System.Console;
class DisplaySomeMoney
{
static void Main()
{
double someMoney = 20.19;
WriteLine("The money is $" + someMoney);
}
}

To make producing output easier, you can combine strings and variable values into a single Write() or WriteLine() statement by concatenating them or by using a format string.

When you concatenate(连接) a string with another value, you join the values with a plus sign.
WriteLine("The money is $" + someMoney);的效果就是打印出The money is $20.19

A format string is a string of characters that controls the appearance of output.

A placeholder holds a position for a variable value within a string. It consists of a pair of curly braces containing a number that indicates the desired variable’s position in a list that follows the string. The first position is always position 0. The curly braces that contain a digit create a placeholder {0} into which the value of someMoney is inserted.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*以下效果相同*/

// 1
WriteLine("The money is ${0} exactly", someMoney);

// 2
string mySentence = String.Format("The money is ${0} exactly", someMoney);
WriteLine(mySentence);

// 3
string mySentence = $"The money is ${someMoney} exactly";
WriteLine(mySentence);

// 4
WriteLine($"The money is ${someMoney} exactly");

其他用法

1
2
3
4
5
6
7
int year1 = 2019;
int year2 = 2026;
WriteLine("This year is {1}, I love the year {0}", year1, year2);

WriteLine("{0}", 4);
WriteLine("{0, 5}", 4); // 右对齐,占5个字宽
WriteLine("{0, -8}{1, -8}", "Banks", "Lee"); // 左对齐,占8个字宽

2.3 Using the Integral Data Types

In C#, nine data types are considered integral data types—that is, types that store whole numbers.
int, byte, sbyte, short, ushort, uint, long, ulong, char

由于每一个Unicode character都可以用数字表示,所以这些类型都表示数字
int占4个字节,可以表示-2147483648到2147483647的整数

2.4 Using Floating-Point Data Types

A value’s number of significant digits(有效数字) specifies the mathematical accuracy of the value.

C# supports three floating-point data types: float, double, and decimal.

  • A float data type can hold as many as seven significant digits of accuracy. For example, a float assigned the value 1234.56789 will appear as 1234.568 because it is accurate only to the seventh digit (the third digit to the right of the decimal point).
  • A double data type can hold 15 or 16 significant digits of accuracy. For example, a double given the value 123456789.987654321 will appear as 123456789.987654 because it is accurate to only the fifteenth digit (the sixth digit to the right of the decimal point).
  • Compared to floats and doubles, the decimal type has a greater precision and a smaller range, which makes it suitable for financial and monetary calculations. A decimal is significant to 28 or 29 digits. A decimal cannot hold as large a value as a double can. (The highest value of a decimal is about 102810^{28}; the highest value of a double is 1030810^{308}, but the decimal will be more accurate to more decimal places.)

scientific notation
例如1.234568E9 = 1234568000, 1.234E-7 = 0.0000001234

格式化内容先略去

2.5 Using Arithmetic Operators

好像和C一样,先略去

2.6 Using the bool Data Type

1
bool isBigger = 6 > 5; // Value stored would be true

注意,WriteLine()打印出的布尔变量的值是首字母大写的True或者False,但程序中的值是true或者false

2.7 Understanding Numeric Type Conversion

看题目是类型转换?用到再看

2.8 Using the char Data Type

The characters used in C# are represented in Unicode, which is a 16-bit coding scheme for characters.

1
2
3
char letter = 'A';
char letter = '\u0041';

Starting with C# version 11, you can use a raw string literal instead of an escape sequence.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 错误写法
string messageError = "Line1
Line2"; // 报错:换行符不是字符串的一部分

// 正确写法1
string message = "Line1\nLine2";

// 正确写法2 raw string literal
string message = """
Line1
Line2
""";
// the opening quotes and closing quotes
// must each occupy their own line


string message = """Say "hello" """;

2.9 Using the string Data Type

In C#, you use the string data type to hold a series of characters. The value of a string is expressed within double quotation marks.

A string is considered equal to, greater than, or less than another string lexically, which in the case of letter values means alphabetically. That is, when you compare two strings, you compare each character in turn from left to right. If each Unicode value is the same, then the strings are equivalent. If any corresponding character values are different, the string that has the greater Unicode value earlier in the string is considered greater.

You can compare strings with any of the following methods:

  1. The Equals() method call takes the format name1.Equals(name2); its value is true or false. The Equals() method uses an object name and a dot before Equals() and another object within the method parentheses.
  2. name1.CompareTo(name2)的value是整数,0代表两个字符串相等,负数代表第一个小,正数代表第二个小
  3. Compare(name1, name2)的value是整数,它的数值和CompareTo()一样

这里要注意的是,string类型是一个类,而string类型的变量name1,name2都是一个对象,比如Equals()就是字符串对象name1的一个实例方法(Instance Method)
而Compare是一个静态方法,它前面不需要一个object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using static System.Console;
using static System.String;
class CompareNames
{
static void Main()
{
string name1 = "Amy";
string name2 = "Amy";
string name3 = "Matthew";
WriteLine("{0} and {1}; Equals() method gives {2}", name1, name2, name1.Equals(name2));
WriteLine("{0} and {1}; CompareTo() method gives {2}", name1, name3, name1.CompareTo(name2));
WriteLine("{0} and {1}; Compare() method gives {2}", name1, name3, Compare(name1, name2));


}
}

In C#, a string is immutable(不可改变的). That is, a string’s value is not actually modified when you assign a new value to it. For example, when you write name = “Amy”; followed by name = “Deshi”;, the first literal string of characters, Amy, still exists in computer memory, but the name variable no longer refers to that string’s memory address. Instead, name refers to a new address where the characters in Deshi are stored.
Programmers might say that name now points to the new address. The situation is different from that with numbers; when you assign a new value to a numeric variable, the value at the named memory address changes, replacing and erasing the original value.

1
2
3
4
5
6
7
8
9
string word = "water";
int a = word.Length; // a = 5
// Length is a property of a string

word.Substring(0, 2)
// 从0开始,取一个长度为2的子串,得到wa

word.Startswith("wa")
// true, 判断word是否以"wa"中的字符开头

2.10 Defining Named Constants and Enumerations

Named constants and enumerations provide the means to label values that will not change during the execution of a program. Each constant is a single value; enumerations are groups of constants.

Sometimes you want to create a named constant, an identifier for a memory location whose contents cannot change.

1
const double TAX_RATE = 0.06;

You must assign a value to a constant when you create it. You can use a constant just as you would use a variable of the same type—for example, display it or use it in a mathematical equation—but you cannot assign any new value to it.

An enumeration is a set of constants represented by identifiers. You place an enumeration in a class outside of any methods. Frequently, programmers place enumerations at the top of a file before the Main() method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum DayOfWeek
{
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}// 0, 1, 2, ...

enum DayOfWeek
{
SUNDAY = 1, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}// 1, 2, 3, ...

enum S
{
A = 65,
B = 27,
C = 5
}

By default, enumeration values are integers. Frequently, the identifiers in an enumeration are meant to hold consecutive values. When you do not supply values for the items in an enum list, they start with 0 and are automatically increased by 1. For example, in the DayOfWeek enumeration, SUNDAY is 0, MONDAY is 1, and so on.

1
2
3
4
5
6
7
8
9
10
DayOfWeek payrollDay;
payrollDay = DayOfWeek.TUESDAY;

int shipDay;
DayOfWeek deliverDay;
shipDay = (int)DayOfWeek.THURSDAY;
deliverDay = (DayOfWeek)shipDay;

WriteLine(shipDay); // Display 5
WriteLine(deliverDay); // Display THURSDAY

2.11 Accepting Console Input

1
string myString = ReadLine();

Read()只读一个字符,ReadLine()读字符直到用户按下回车

If you want to use the input value as a type other than string, then you must use a conversion method to change the input string to the proper type. Two methods are available for converting strings—one uses the Convert class and the other uses Parse() methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using static System.Console;
class InteractiveSalesTax
{
static void Main()
{
const double TAX_RATE = 0.06;
string itemPriceAsString;
double itemPrice;
double total;
Write("Enter the price of an item >> ");
itemPriceAsString = ReadLine();
itemPrice = Convert.ToDouble(itemPriceAsString);
total = itemPrice * TAX_RATE;
WriteLine("With a tax rate of {0}, a {1} item " +
"costs {2} more.", TAX_RATE, itemPrice.ToString("C"),total.ToString("C"));
}
}

This conversion is accomplished using the Convert class ToDouble() method.
其实也可以

1
itemPrice = Convert.ToDouble(ReadLine());

还可以

1
2
3
4
5
6
itemPrice = double.Parse(itemPriceAsString);

itemPrice = Double.Parse(itemPriceAsString);

score = int.Parse(ReadLine());
score = Int32.Parse(ReadLine());

Each of the previous two statements uses a Parse() method defined in the Double class. You can use the system type name Double or its simple type name double.