C#: 关键字指南

abstract, as, base, bool, break, byte, case, catch, char, checked, class, const, continue, decimal, default, delegate, do, double, else, enum, event, explicit, extern, false, finally, fixed, float, for, foreach, goto, if, implicit, in, int, interface, internal, is, lock, long, namespace, new, null, object, operator, out, override, params, private, protected, public, readonly, ref, return, sbyte, sealed, short, sizeof, stackalloc, static, string, struct, switch, this, throw, true, try, typeof, uint, ulong, unchecked, unsafe, ushort, using, virtual, void, volatile, while.  

abstract

在 C# 中,abstract 关键字用于定义抽象类和抽象方法。抽象类是不能被实例化的类,而抽象方法是没有实现的方法,需要在子类中被实现。 

抽象类

抽象类是用于表示一类对象的基类,但是它本身不能被实例化。抽象类通常包含一些抽象方法,这些方法需要在子类中被实现。抽象类可以包含非抽象方法和字段,这些成员可以被子类继承和使用。

定义抽象类的语法如下: 

abstract class MyClass
{
    // 抽象方法
    public abstract void MyMethod();
 
    // 非抽象方法
    public void MyOtherMethod()
    {
        // ...
    }
}

抽象方法

抽象方法是没有实现的方法,需要在子类中被实现。抽象方法只有方法签名,没有方法体。定义抽象方法的语法如下:

abstract class MyClass
{
    public abstract void MyMethod();
}

子类必须实现抽象方法,否则会编译错误。例如: 

class MyDerivedClass : MyClass
{
    public override void MyMethod()
    {
        // 实现抽象方法
    }
}

总结 

abstract 关键字用于定义抽象类和抽象方法。抽象类是不能被实例化的类,而抽象方法是没有实现的方法,需要在子类中被实现。抽象类可以包含非抽象方法和字段,这些成员可以被子类继承和使用。子类必须实现抽象方法,否则会编译错误。

as

as 关键字在 C# 中用于显式类型转换。它允许您将一个类型的对象转换为另一个类型,前提是转换是有效的。 

以下是 as 关键字在 C# 中的使用示例: 

object obj = "Hello World";
string str = obj as string;

在上面的代码中,我们有一个包含字符串 "Hello World" 的对象 obj。然后,我们使用 as 关键字将 obj 转换为字符串类型,并将其赋值给变量 str。如果转换无效,则 str 将被赋予空值。

base

base 关键字,它用于访问基类中的成员。在派生类中,我们可以使用 base 关键字来调用基类中的构造函数、方法和属性。 

访问基类构造函数

在派生类的构造函数中,我们可以使用 base 关键字来调用基类的构造函数。这样做的好处是可以在派生类的构造函数中初始化基类中的字段。 

以下是一个例子: 

public class MyBaseClass
{
    private int myField;
 
    public MyBaseClass(int myField)
    {
        this.myField = myField;
    }
}
 
public class MyDerivedClass : MyBaseClass
{
    public MyDerivedClass(int myField) : base(myField)
    {
    }
}

在上面的例子中,MyDerivedClass 继承自 MyBaseClass。在 MyDerivedClass 的构造函数中,我们使用 base 关键字来调用 MyBaseClass 的构造函数,并将 myField 参数传递给它。 

访问基类方法和属性

在派生类中,我们可以使用 base 关键字来调用基类中的方法和属性。以下是一个例子: 

public class MyBaseClass
{
    public virtual void MyMethod()
    {
        Console.WriteLine("MyBaseClass.MyMethod");
    }
 
    public virtual int MyProperty
    {
        get { return 42; }
    }
}
 
public class MyDerivedClass : MyBaseClass
{
    public override void MyMethod()
    {
        base.MyMethod();
        Console.WriteLine("MyDerivedClass.MyMethod");
    }
 
    public override int MyProperty
    {
        get { return base.MyProperty + 1; }
    }
}

在上面的例子中,MyDerivedClass 继承自 MyBaseClass。在 MyDerivedClass 中,我们重写了 MyMethod 和 MyProperty 方法,并使用 base 关键字来调用基类中的方法和属性。

bool 

bool 关键字,用于表示布尔值,即 true 或 false。 

在 C# 中,布尔类型是一种基本数据类型,可以用于逻辑运算和条件语句中。例如,可以使用布尔类型来表示某个条件是否成立,或者在循环中判断是否继续执行。

以下是一个简单的示例,演示了如何使用 bool 类型: 

bool isTrue = true;
bool isFalse = false;
 
if (isTrue)
{
    Console.WriteLine("isTrue is true");
}
 
if (!isFalse)
{
    Console.WriteLine("isFalse is false");
}

在上面的示例中,我们定义了两个布尔变量 isTrue 和 isFalse,并使用 if 语句检查它们的值。第一个 if 语句检查 isTrue 是否为 true,如果是,则输出一条消息。第二个 if 语句使用逻辑非运算符 ! 检查 isFalse 是否为

false,如果是,则输出一条消息。除了 true 和 false,布尔类型还可以使用以下方式进行初始化:
  • bool isTrue = true;
  • bool isFalse = false;
  • bool isBool = bool.Parse("True");
  • bool isBool = bool.Parse("False");
  • bool isBool = bool.TryParse("True", out bool result);
  • bool isBool = bool.TryParse("False", out bool result);

其中,bool.Parse 方法将字符串转换为布尔值,如果字符串不是有效的布尔值,则会引发异常。bool.TryParse 方法也将字符串转换为布尔值,但如果字符串不是有效的布尔值,则不会引发异常,而是将结果设置为false

break 

break 关键字,用于在循环语句中提前结束循环。当 break 语句被执行时,程序将跳出当前循环并继续执行循环后面的代码。 

以下是一个使用 break 的示例: 

while (true)
{
    // do something
    if (condition)
    {
        break;
    }
    // do something else
}

在上面的代码中,当 condition 满足时,break 语句将被执行,程序将跳出循环并继续执行循环后面的代码。 

需要注意的是,break 只能用于循环语句中,不能用于其他语句中。如果在非循环语句中使用 break,编译器将会报错。 

byte 

byte 关键字,用于声明一个 8 位无符号整数。byte 类型的变量可以存储 0 到 255 之间的整数。 

以下是一个使用 byte 的示例: 

byte b = 255;

 在上面的代码中,b 是一个 byte 类型的变量,它存储了一个值为 255 的整数。 

需要注意的是,byte 类型的变量只能存储 0 到 255 之间的整数。如果存储的值超出了这个范围,编译器将会报错。 

case 

case 关键字,用于在 switch 语句中匹配一个常量表达式。 

以下是一个使用 case 的示例: 

switch (variable)
{
    case 1:
        // do something
        break;
    case 2:
        // do something else
        break;
    default:
        // do something if none of the cases match
        break;
}

在上面的代码中,case 用于匹配 variable 的值。如果 variable 的值等于 1,则执行第一个 case 中的代码;如果 variable 的值等于 2,则执行第二个 case 中的代码;如果 variable 的值不等于 1 或 2,则执行 default 中的代码。 

需要注意的是,每个 case 后面必须跟一个 break 语句,否则程序将会继续执行下一个 case 中的代码。如果没有匹配的 case,则执行 default 中的代码。

catch 

catch 关键字,用于捕获异常并处理异常情况。在 try 块中,如果发生了异常,程序将跳转到 catch 块中执行相应的代码。 

以下是一个使用 catch 的示例: 

try
{
    // do something that may throw an exception
}
catch (Exception ex)
{
    // handle the exception
}

在上面的代码中,try 块中的代码可能会抛出异常。如果发生了异常,程序将跳转到 catch 块中执行相应的代码。catch 块中的参数 ex 是一个 Exception 类型的变量,它用于存储捕获到的异常信息。 

需要注意的是,catch 块必须跟在 try 块后面,并且可以有多个 catch 块来处理不同类型的异常。如果没有发生异常,程序将跳过 catch 块并继续执行后面的代码。

char 

char 关键字,用于声明一个 Unicode 字符。char 类型的变量可以存储任意 Unicode 字符。 
以下是一个使用 char 的示例: 
char c = 'A';

 

在上面的代码中,c 是一个 char 类型的变量,它存储了一个 Unicode 字符 'A'。 

需要注意的是,char 类型的变量只能存储一个字符。如果需要存储多个字符,可以使用字符串类型 string。 

另外,char 类型的变量可以使用转义字符来表示一些特殊字符,例如: 

char c = '\n'; // 表示换行符

checked 

checked 关键字,用于在进行算术运算时检查是否发生了溢出。如果发生了溢出,程序将抛出 System.OverflowException 异常。 

以下是一个使用 checked 的示例: 

int a = int.MaxValue;
int b = 1;
int c = checked(a + b); // 抛出 System.OverflowException 异常

在上面的代码中,a 的值为 int.MaxValue,b 的值为 1。由于 a 和 b 相加的结果超出了 int 类型的取值范围,因此程序将抛出 System.OverflowException 异常。 

需要注意的是,checked 关键字只对当前语句块中的算术运算有效。如果需要对整个方法或类中的算术运算进行检查,可以使用 checked 块。 

以下是一个使用 checked 块的示例: 

checked
{
    int a = int.MaxValue;
    int b = 1;
    int c = a + b; // 抛出 System.OverflowException 异常
}

在上面的代码中,checked 块中的所有算术运算都将进行溢出检查。

class 

class 关键字,用于定义一个类。类是 C# 中的基本概念之一,用于封装数据和行为。 

以下是一个使用 class 的示例: 

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
 
    public void SayHello()
    {
        Console.WriteLine("Hello, my name is " + Name + " and I am " + Age + " years old.");
    }
}

在上面的代码中,Person 是一个类,它有两个属性 Name 和 Age,以及一个方法 SayHello。属性用于存储数据,方法用于定义行为。 

需要注意的是,类必须包含在命名空间中。命名空间用于组织代码,避免命名冲突。

以下是一个包含 Person 类的命名空间的示例: 

namespace MyNamespace
{
    class Person
    {
        // ...
    }
}

另外,类可以继承自其他类。继承是一种重要的面向对象编程概念,它允许子类继承父类的属性和方法,并可以添加自己的属性和方法。以下是一个继承自 Person 类的 Student 类的示例:

class Student : Person
{
    public string School { get; set; }
 
    public void Study()
    {
        Console.WriteLine("I am studying at " + School + ".");
    }
}

在上面的代码中,Student 类继承自 Person 类,并添加了一个属性 School 和一个方法 Study。 

const 

const 关键字,用于声明一个常量。常量是一种特殊的变量,它的值在声明后不能被修改。 

以下是一个使用 const 的示例: 

const int MaxValue = 100;

在上面的代码中,MaxValue 是一个常量,它的值为 100。由于 MaxValue 是一个常量,因此它的值在声明后不能被修改。 

需要注意的是,常量必须在声明时进行初始化,并且只能使用常量表达式进行初始化。常量表达式是一种在编译时可以确定值的表达式,例如: 

const int MaxValue = 100 + 200; // 合法的常量表达式
const int MinValue = GetMinValue(); // 非法的常量表达式

在上面的代码中,MaxValue 的初始化表达式是一个常量表达式,因此它是合法的。而 MinValue 的初始化表达式调用了一个方法 GetMinValue(),因此它不是常量表达式,是非法的。 

另外,常量可以用于各种数据类型,包括整型、浮点型、字符型、字符串型等等。以下是一些常量的示例: 

const double Pi = 3.1415926;
const char NewLine = '\n';
const string Greeting = "Hello, world!";

continue

continue 关键字,用于在循环语句中跳过当前迭代并进入下一次迭代。
continue 通常与 forwhiledo-while 等循环语句一起使用。在循环语句中使用 continue 可以跳过某些特定的值或条件,从而使程序更加高效。

需要注意的是,continue 关键字只能在循环语句中使用。如果在非循环语句中使用 continue,编译器将会报错。 

以下是一个使用 continue 的示例: 

int i = 0;
while (i < 10)
{
    i++;
    if (i % 2 == 0)
    {
        continue;
    }
    Console.WriteLine(i);
}

在上面的代码中,我们使用 while 循环从 1 到 10 迭代。然而,我们使用 continue 关键字跳过任何偶数并仅打印奇数。因此,这段代码的输出将是:

0、2、4、6、8

你还可以使用标签和 continue 关键字一起跳过嵌套循环中的特定值。以下是一个示例:

 
for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        if (j == 5)
        {
            continue;
        }
        Console.WriteLine(i + "," + j);
    }
}

在上面的代码中,我们使用嵌套的 for 循环来迭代从 0 到 9 的所有 i 和 j 的组合。然而,我们使用 continue 来跳过任何值等于 5 的 j。因此,这段代码的输出将是除了 j 等于 5 的所有 i 和 j。

decimal

decimal是C#中的一种数据类型,用于表示十进制数。它比doublefloat更精确,因为它可以存储更多的小数位。在需要高精度计算的场景下,decimal是一个非常有用的数据类型。

以下是一些关于decimal的特点和用法: 

  • decimal类型的变量可以使用Mm后缀来声明。例如:
    decimal myDecimal = 123.45M;
  • decimal类型的默认值为0M
  • decimal类型的运算符和其他数字类型一样,包括+-*/等。
  • decimal类型的运算符可以与其他数字类型进行混合运算,但需要进行类型转换。
  • decimal类型的精度为28-29位小数,而double类型的精度为15-16位小数。
  • decimal类型的范围为±1.0 x 10^-28 到 ±7.9 x 10^28。

以下是一个使用decimal类型的示例代码: 

decimal price = 19.99M;
decimal taxRate = 0.08M;
decimal taxAmount = price * taxRate;
decimal total = price + taxAmount;
Console.WriteLine("Price: {0:C}", price);
Console.WriteLine("Tax: {0:C}", taxAmount);
Console.WriteLine("Total: {0:C}", total);

在上面的示例中,我们使用decimal类型来计算商品价格、税率、税额和总价,并使用Console.WriteLine方法将结果输出到控制台。 

default 

default关键字,用于获取类型的默认值。当我们声明一个变量但没有给它赋值时,它的值将会是该类型的默认值。例如,int类型的默认值为0bool类型的默认值为false

以下是一些关于default的特点和用法: 

  • default关键字可以用于任何类型,包括值类型和引用类型。
  • 对于值类型default关键字返回该类型的零值。例如,default(int)返回0,default(bool)返回false。对于引用类型,default关键字返回null。
  • default关键字可以用于泛型类型参数,以获取该类型的默认值。例如,default(T)返回T类型的默认值。
  • default关键字可以用于switch语句中的case分支,以表示默认分支。例如: 
switch (myVariable)
{
    case 1:
        // do something
        break;
    case 2:
        // do something else
        break;
    default:
        // do default action
        break;
}

在上面的示例中,如果myVariable的值既不是1也不是2,则执行默认分支。

delegate

delegate关键字,用于声明委托类型。委托类型是一种可以封装方法的类型,它可以用于回调函数、事件处理程序等场景。以下是一些关于delegate的特点和用法: 
  •  delegate关键字用于声明委托类型。例如,下面的代码声明了一个名为MyDelegate的委托类型,它可以封装一个返回int类型、参数为string类型的方法:

    delegate int MyDelegate(string arg);
  • 委托类型可以用于声明委托变量。例如,下面的代码声明了一个名为myDelegate的委托变量,它可以引用一个返回int类型、参数为string类型的方法: 

    MyDelegate myDelegate = MyMethod;
  • 委托变量可以通过+=-=运算符来添加和移除方法。例如,下面的代码添加了一个名为MyOtherMethod的方法到myDelegate中:

    myDelegate += MyOtherMethod;
  • 委托变量可以通过()运算符来调用封装的方法。例如,下面的代码调用了myDelegate中封装的方法,并将"hello"作为参数传递给它:

    int result = myDelegate("hello");
  • 委托类型可以用于声明事件。例如,下面的代码声明了一个名为MyEvent的事件,它使用MyDelegate类型作为事件处理程序的类型: 

    event MyDelegate MyEvent;
  • 事件可以通过+=-=运算符来添加和移除事件处理程序。例如,下面的代码添加了一个名为MyEventHandler的事件处理程序到MyEvent中:

    MyEvent += MyEventHandler;

do

do关键字,用于声明do-while循环。do-while循环是一种先执行循环体,再判断循环条件的循环结构。以下是一些关于do的特点和用法:  

do关键字用于声明do-while循环。例如,下面的代码声明了一个do-while循环,它会一直执行循环体,直到conditionfalse 
do
{
    // do something
} while (condition);
  • do-while循环至少会执行一次循环体,即使循环条件一开始就为false

  • do-while循环可以用于需要至少执行一次的循环场景,例如读取用户输入、处理异常等。

double

double关键字,用于声明双精度浮点数类型。双精度浮点数类型可以表示更大范围和更高精度的实数值,它通常用于需要更高精度计算的场景,例如科学计算、金融计算等。 

以下是一些关于double的特点和用法: 

  •  double关键字用于声明双精度浮点数类型。例如,下面的代码声明了一个名为myDouble的双精度浮点数变量: 

    double myDouble = 3.14159;
  • 双精度浮点数类型可以表示的范围为±5.0 × 10^-324到±1.7 × 10^308,精度为15-16位小数。

  • 双精度浮点数类型可以进行基本的算术运算,例如加减乘除、取余等。例如,下面的代码计算了两个双精度浮点数的和: 

    double result = myDouble1 + myDouble2;
  • 双精度浮点数类型可以进行比较运算,例如等于、大于、小于等。需要注意的是,由于浮点数的精度问题,比较运算可能会出现意外的结果。例如,下面的代码比较了两个双精度浮点数的大小: 

    bool isGreater = myDouble1 > myDouble2;

else

else关键字,用于在条件语句中指定当条件不成立时要执行的代码块。以下是一些关于else的特点和用法: 
  •  else关键字通常与if关键字一起使用,用于指定当if条件不成立时要执行的代码块。例如,下面的代码使用了ifelse关键字,根据condition的值来执行不同的代码块: 

    if (condition)
    {
        // do something if condition is true
    }
    else
    {
        // do something else if condition is false
    }
  • else关键字也可以与if关键字的嵌套使用,用于指定多个条件的执行代码块。例如,下面的代码使用了两个if和一个else关键字,根据condition1condition2的值来执行不同的代码块: 
     
    if (condition1)
    {
        // do something if condition1 is true
    }
    else if (condition2)
    {
        // do something else if condition2 is true
    }
    else
    {
        // do something else if both condition1 and condition2 are false
    }
  •  else关键字可以省略,只使用if关键字来指定条件语句。这种情况下,如果条件不成立,则不执行任何代码。例如,下面的代码只使用了if关键字,如果condition不成立,则不执行任何代码: 

    if (condition)
    {
        // do something if condition is true
    }

     

enum

enum关键字,用于声明枚举类型。枚举类型是一种用户自定义的类型,它可以包含一组命名的常量值,这些常量值可以作为变量使用。以下是一些关于enum的特点和用法:
  •  enum关键字用于声明枚举类型。例如,下面的代码声明了一个名为Color的枚举类型,它包含了三个常量值RedGreenBlue 

    enum Color
    {
        Red,
        Green,
        Blue
    }
  • 枚举类型的常量值默认从0开始递增,但是可以手动指定每个常量值的数值。例如,下面的代码声明了一个名为Size的枚举类型,它手动指定了每个常量值的数值: 

    enum Size
    {
        Small = 1,
        Medium = 2,
        Large = 3
    }
  • 枚举类型的常量值可以作为变量使用。例如,下面的代码声明了一个名为myColorColor类型变量,并将其赋值为Green 

    Color myColor = Color.Green;
  • 枚举类型的常量值可以用于条件语句中。例如,下面的代码使用了switch语句和Color类型的常量值来执行不同的代码块: 

    switch (myColor)
    {
        case Color.Red:
            // do something if myColor is Red
            break;
        case Color.Green:
            // do something if myColor is Green
            break;
        case Color.Blue:
            // do something if myColor is Blue
            break;
        default:
            // do something if myColor is not Red, Green or Blue
            break;
    }

 

event

event关键字,用于声明事件。事件是一种特殊的委托类型,它可以在对象之间传递消息,使得一个对象可以通知其他对象发生了某个特定的事件。以下是一些关于event的特点和用法: 
  •  event关键字用于声明事件。例如,下面的代码声明了一个名为myEvent的事件: 

    public event EventHandler myEvent;
  • 事件必须与委托类型一起使用。例如,上面的代码中,EventHandler是一个委托类型,它定义了事件处理程序的签名。 

  • 事件可以在类中声明,也可以在接口中声明。例如,下面的代码声明了一个名为IMyInterface的接口,它包含了一个名为MyEvent的事件: 

    interface IMyInterface
    {
        event EventHandler MyEvent;
    }
  • 事件可以使用+=-=运算符来添加和移除事件处理程序。例如,下面的代码添加了一个名为myHandler的事件处理程序: 

    myEvent += myHandler;
  • 事件处理程序必须与事件的委托类型具有相同的签名。例如,如果事件的委托类型是EventHandler,则事件处理程序必须具有以下签名: 

    void MyEventHandler(object sender, EventArgs e)
  • 事件处理程序可以是任何方法,只要它们与事件的委托类型具有相同的签名。例如,下面的代码定义了一个名为myHandler的方法,它与EventHandler委托类型具有相同的签名: 

    void myHandler(object sender, EventArgs e)
    {
        // do something when the event is raised
    }

 

explicit

explicit关键字,用于声明显式转换运算符。显式转换运算符是一种特殊的方法,它可以将一个对象从一种类型转换为另一种类型。以下是一些关于explicit的特点和用法: 
  •  explicit关键字用于声明显式转换运算符。例如,下面的代码声明了一个名为MyClass的类,并在其中定义了一个名为explicit operator int(MyClass myClass)的显式转换运算符: 

    class MyClass
    {
        public static explicit operator int(MyClass myClass)
        {
            // convert myClass to an int
        }
    }
  • 显式转换运算符必须是公共的和静态的,并且必须返回要转换的类型。例如,上面的代码中,explicit operator int表示将MyClass类型转换为int类型。 

  • 显式转换运算符可以将一个对象从一种类型转换为另一种类型。例如,下面的代码将一个名为myClassMyClass类型对象转换为int类型: 

    MyClass myClass = new MyClass();
    int myInt = (int)myClass;
  • 显式转换运算符可以用于条件语句中。例如,下面的代码使用了if语句和MyClass类型的对象来执行不同的代码块:

    MyClass myClass = new MyClass();
    if (myClass == 0)
    {
        // do something if myClass is equal to 0
    }
    else
    {
        // do something else if myClass is not equal to 0
    }

     

extern

extern关键字,用于声明外部方法。外部方法是一种特殊的方法,它在C#代码中没有实现,而是在其他地方实现,例如在C++代码中。以下是一些关于extern的特点和用法: 
  •  extern关键字用于声明外部方法。例如,下面的代码声明了一个名为MessageBox的外部方法: 

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);
  • 外部方法必须使用DllImport属性来指定它们的实现。例如,上面的代码中,user32.dll是包含MessageBox方法实现的动态链接库的名称。 

  • 外部方法可以在类中声明,也可以在接口中声明。例如,下面的代码声明了一个名为IMyInterface的接口,它包含了一个名为MyMethod的外部方法: 

    interface IMyInterface
    {
        [DllImport("mylib.dll")]
        void MyMethod();
    }
  • 外部方法可以使用unsafe关键字来声明不安全的代码块。例如,下面的代码声明了一个名为MyMethod的外部方法,并使用了unsafe关键字: 

    [DllImport("mylib.dll")]
    unsafe static extern void MyMethod(byte* buffer, int length);
  • 外部方法可以使用refout关键字来传递引用参数。例如,下面的代码声明了一个名为MyMethod的外部方法,并使用了ref关键字:  

    [DllImport("mylib.dll")]
    static extern void MyMethod(ref int value);

false

false关键字,表示布尔类型的假值。以下是一些关于false的特点和用法: 
  •  false关键字用于表示布尔类型的假值。例如,下面的代码将一个名为myBool的布尔类型变量初始化为false 

    bool myBool = false;
  • false关键字可以用于条件语句中。例如,下面的代码使用了if语句和布尔类型的变量来执行不同的代码块: 
    bool myBool = false;
    if (myBool)
    {
        // do something if myBool is true
    }
    else
    {
        // do something else if myBool is false
    }
  • false关键字可以与true关键字一起使用,表示布尔类型的真假值。例如,下面的代码使用了if语句和布尔类型的变量来执行不同的代码块:  
    bool myBool = false;
    if (myBool == true)
    {
        // do something if myBool is true
    }
    else
    {
        // do something else if myBool is false
    }

     

finally

finally关键字,用于定义一个代码块,该代码块在try块中的代码执行完毕后始终执行。以下是一些关于finally的特点和用法: 
  •  finally关键字用于定义一个代码块,该代码块在try块中的代码执行完毕后始终执行。例如,下面的代码使用了tryfinally语句来确保文件流被正确关闭: 

    FileStream fileStream = null;
    try
    {
        fileStream = new FileStream("file.txt", FileMode.Open);
        // do something with fileStream
    }
    finally
    {
        if (fileStream != null)
        {
            fileStream.Close();
        }
    }
  •  finally块中的代码始终会被执行,无论try块中的代码是否抛出异常。例如,下面的代码使用了tryfinally语句来确保文件流被正确关闭,即使在try块中的代码抛出异常: 

    FileStream fileStream = null;
    try
    {
        fileStream = new FileStream("file.txt", FileMode.Open);
        // do something with fileStream
        throw new Exception("Something went wrong");
    }
    finally
    {
        if (fileStream != null)
        {
            fileStream.Close();
        }
    }
  •  finally块中的代码可以用于清理资源,例如关闭文件流或释放内存。例如,下面的代码使用了tryfinally语句来确保文件流被正确关闭: 

    FileStream fileStream = null;
    try
    {
        fileStream = new FileStream("file.txt", FileMode.Open);
        // do something with fileStream
    }
    finally
    {
        if (fileStream != null)
        {
        fileStream.Close();
        }
    }

fixed

fixed关键字,用于声明一个指针变量,并将其固定在内存中,以便在不移动内存的情况下访问它。以下是一些关于fixed的特点和用法: 
  •  fixed关键字用于声明一个指针变量,并将其固定在内存中。例如,下面的代码声明了一个名为myArray的整数数组,并使用fixed关键字将其固定在内存中: 

    int[] myArray = new int[10];
    fixed (int* p = myArray)
    {
        // do something with p
    }
  •  fixed关键字只能用于指针类型。例如,下面的代码声明了一个名为myPointer的指针变量,并使用fixed关键字将其固定在内存中: 

    int* myPointer = null;
    fixed (int* p = &myPointer)
    {
        // do something with p
    }
  •  fixed关键字可以用于声明不安全的代码块。例如,下面的代码声明了一个名为MyMethod的方法,并使用了unsafe关键字和fixed关键字:

    unsafe static void MyMethod(byte* buffer, int length)
    {
        fixed (byte* p = buffer)
        {
            // do something with p
        }
    }
  •  fixed关键字可以用于提高性能。由于固定了指针变量,因此可以避免垃圾回收器移动内存,从而提高代码的性能。但是,使用fixed关键字也可能会导致内存泄漏和安全问题,因此需要谨慎使用。

     

float

float关键字,表示单精度浮点数类型。以下是一些关于float的特点和用法:
  •  float关键字用于表示单精度浮点数类型。例如,下面的代码将一个名为myFloat的单精度浮点数变量初始化为0.0f:  

    float myFloat = 0.0f;
  •  float关键字可以用于表示小数。例如,下面的代码将一个名为myFloat的单精度浮点数变量初始化为3.14f 

    float myFloat = 3.14f;
  •  float关键字可以用于进行数学运算。例如,下面的代码将两个单精度浮点数相加并将结果存储在一个名为result的变量中: 

    float num1 = 1.5f;
    float num2 = 2.5f;
    float result = num1 + num2;  
  • float关键字可以与其他数据类型进行转换。例如,下面的代码将一个名为myInt的整数变量转换为单精度浮点数类型: 
    int myInt = 10;
    float myFloat = (float)myInt;

for

for关键字,用于循环执行一段代码。for循环通常用于已知循环次数的情况下,可以在循环中使用计数器来控制循环次数。 

for循环由三个部分组成:初始化、条件和迭代器。初始化部分在循环开始前执行一次,通常用于初始化计数器。条件部分在每次循环开始前检查,如果条件为真,则执行循环体。迭代器部分在每次循环结束后执行,通常用于更新计数器。

以下是一个使用for循环的示例代码: 

for (int i = 0; i < 10; i++)
{
    Console.WriteLine(i);
}

在上面的代码中,for循环的初始化部分初始化了一个整数变量i,并将其设置为0。条件部分检查i是否小于10,如果是,则执行循环体。循环体中的代码打印i的值。迭代器部分将i的值增加1。

除了上面的示例代码中使用的整数计数器外,for循环还可以使用其他类型的计数器,例如浮点数或日期时间。此外,for循环还可以嵌套在其他循环中,例如while循环或foreach循环中。 

foreach 

foreach关键字,用于循环遍历集合中的元素。foreach循环通常用于不知道循环次数的情况下,可以在循环中遍历集合中的每个元素。 
foreach循环由两个部分组成:集合和循环变量。集合是要遍历的对象,可以是数组、列表、字典等。循环变量是一个临时变量,用于存储集合中的每个元素。 

以下是一个使用foreach循环的示例代码: 

int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
    Console.WriteLine(number);
}

在上面的代码中,foreach循环遍历了一个整数数组numbers中的每个元素,并将其存储在循环变量number中。循环体中的代码打印number的值。 

除了上面的示例代码中使用的整数数组外,foreach循环还可以用于遍历其他类型的集合,例如列表、字典等。此外,foreach循环还可以嵌套在其他循环中,例如for循环或while循环中。

goto 

goto关键字,用于无条件跳转到程序中的另一个位置。
goto语句通常用于跳出多层循环或在程序中实现类似于switch语句的功能。 

以下是一个使用goto语句的示例代码: 

int i = 0;
start:
    Console.WriteLine(i);
    i++;
    if (i < 10)
        goto start;

在上面的代码中,goto语句用于跳转到标记为start的位置。循环体中的代码打印i的值,并将其增加1。如果i小于10,则跳转到标记为start的位置。 

虽然goto语句可以使程序更加简洁,但它也可能导致代码难以理解和维护。因此,在编写代码时应该尽量避免使用goto语句,而是使用更加结构化的控制流语句,例如if语句、while循环和for循环等。 

if

if关键字,用于根据条件执行不同的代码。if语句通常用于在程序中进行条件判断,如果条件为真,则执行一段代码,否则执行另一段代码。 

以下是一个使用if语句的示例代码: 

int x = 10;
if (x > 0)
{
    Console.WriteLine("x是正数");
}
else if (x < 0)
{
    Console.WriteLine("x是负数");
}
else
{
    Console.WriteLine("x是零");
}

在上面的代码中,if语句用于判断变量x的值。如果x大于0,则打印x是正数;如果x小于0,则打印x是负数;否则打印x是零。 

除了上面的示例代码中使用的整数比较外,if语句还可以使用其他类型的比较,例如字符串比较、布尔比较等。

此外,if语句还可以嵌套在其他if语句中,或与其他控制流语句(例如for循环、while循环等)结合使用。

implicit

implicit关键字,用于定义隐式类型转换。隐式类型转换是指在不需要显式转换的情况下,将一种类型的值转换为另一种类型的值。 

以下是一个使用implicit关键字定义隐式类型转换的示例代码: 

class Celsius
{
    public double Temperature { get; set; }
 
    public static implicit operator Fahrenheit(Celsius celsius)
    {
        return new Fahrenheit()
        {
            Temperature = (celsius.Temperature * 9 / 5) + 32
        };
    }
}
 
class Fahrenheit
{
    public double Temperature { get; set; }
}
 
class Program
{
    static void Main(string[] args)
    {
        Celsius celsius = new Celsius() { Temperature = 0 };
        Fahrenheit fahrenheit = celsius;
        Console.WriteLine(fahrenheit.Temperature);
    }
}

在上面的代码中,Celsius类定义了一个Temperature属性,表示摄氏温度。Fahrenheit类也定义了一个Temperature属性,表示华氏温度。

Celsius类中定义了一个隐式类型转换运算符,将Celsius类型的值转换为Fahrenheit类型的值。

在Main方法中,创建了一个Celsius对象,并将其赋值给Fahrenheit类型的变量fahrenheit。由于Celsius类定义了隐式类型转换运算符,因此可以将Celsius类型的值隐式转换为Fahrenheit类型的值。

最后,打印fahrenheit.Temperature的值,即0摄氏度对应的华氏温度。 

除了上面的示例代码中使用的自定义类型外,implicit关键字还可以用于定义基本类型之间的隐式类型转换,例如将int类型的值隐式转换为long类型的值。

is

is关键字,用于检查一个对象是否是指定类型或其派生类型的实例。is关键字通常用于在程序中进行类型检查,以确保对象具有所需的类型。
以下是一个使用is关键字进行类型检查的示例代码: 
class Animal { }
class Dog : Animal { }
 
class Program
{
    static void Main(string[] args)
    {
        Animal animal = new Dog();
        if (animal is Dog)
        {
            Console.WriteLine("这是一只狗");
        }
        else
        {
            Console.WriteLine("这不是一只狗");
        }
    }
}

 

在上面的代码中,Animal类是一个基类,Dog类是Animal类的派生类。在Main方法中,创建了一个Dog对象,并将其赋值给Animal类型的变量animal

然后,使用is关键字检查animal对象是否是Dog类型的实例。由于animal对象是Dog类型的实例,因此打印这是一只狗。 

除了上面的示例代码中使用的类类型外,is关键字还可以用于检查基本类型的值是否属于指定的范围,例如检查一个整数是否在指定的区间内。

lock 

lock关键字,用于在多线程编程中实现互斥锁。互斥锁是一种同步机制,用于确保在任何时候只有一个线程可以访问共享资源。 

以下是一个使用lock关键字实现互斥锁的示例代码: 

class Counter
{
    private int count = 0;
    private object lockObject = new object();
 
    public void Increment()
    {
        lock (lockObject)
        {
            count++;
        }
    }
 
    public void Decrement()
    {
        lock (lockObject)
        {
            count--;
        }
    }
 
    public int GetCount()
    {
        lock (lockObject)
        {
            return count;
        }
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        Counter counter = new Counter();
        Task[] tasks = new Task[10];
        for (int i = 0; i < 10; i++)
        {
            tasks[i] = Task.Run(() =>
            {
                for (int j = 0; j < 1000; j++)
                {
                    counter.Increment();
                }
            });
        }
        Task.WaitAll(tasks);
        Console.WriteLine(counter.GetCount());
    }
}    

在上面的代码中,Counter类表示一个计数器,其中包含Increment、Decrement和GetCount方法。这些方法都使用lock关键字来实现互斥锁,以确保在任何时候只有一个线程可以访问计数器。

Main方法中,创建了一个Counter对象,并启动了10个任务,每个任务都会调用Increment方法1000次。最后,打印计数器的值,即所有任务调用Increment方法的总次数。 

除了上面的示例代码中使用的对象锁外,lock关键字还可以用于锁定其他类型的对象,例如字符串、数组等。

long

long关键字,用于声明一个64位有符号整数类型的变量。long类型的变量可以存储范围更大的整数值,其范围为-9,223,372,036,854,775,808到9,223,372,036,854,775,807。 

以下是一个使用long关键字声明变量的示例代码: 

long number = 1234567890123456789L;
Console.WriteLine(number);

在上面的代码中,使用long关键字声明了一个名为number的变量,并将其初始化为一个64位整数值。由于整数值超出了int类型的范围,因此需要在数字后面添加一个L后缀,以指示这是一个long类型的值。

然后,使用Console.WriteLine方法打印number变量的值。 

除了上面的示例代码中使用的变量类型外,long关键字还可以用于声明long[]类型的数组,以及在方法参数和返回值中使用long类型。

namespace 

namespace关键字,用于定义命名空间。命名空间是一种组织代码的方式,可以将相关的类、接口、结构体和枚举类型组织在一起,以便更好地管理和维护代码。 

以下是一个使用namespace关键字定义命名空间的示例代码: 

namespace MyNamespace
{
    class MyClass
    {
        public void MyMethod()
        {
            Console.WriteLine("Hello, world!");
        }
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        MyNamespace.MyClass myObject = new MyNamespace.MyClass();
        myObject.MyMethod();
    }
}

在上面的代码中,使用namespace关键字定义了一个名为MyNamespace的命名空间,并在其中定义了一个名为MyClass的类。MyClass类包含一个名为MyMethod的方法,该方法打印Hello, world!。

在Main方法中,创建了一个MyClass对象,并调用了MyMethod方法。 

除了上面的示例代码中使用的命名空间外,namespace关键字还可以用于定义嵌套命名空间、别名命名空间和全局命名空间。嵌套命名空间是指在一个命名空间中定义另一个命名空间,以便更好地组织代码。

别名命名空间是指为一个命名空间定义一个别名,以便更方便地使用该命名空间中的类型。

全局命名空间是指没有任何命名空间限定符的类型,这些类型可以在任何命名空间中使用。

new 

new关键字,用于创建新的对象或隐藏基类成员。在创建新的对象时,new关键字可以用于隐藏基类中具有相同名称的成员,以便在派生类中定义新的成员。在隐藏基类成员时,可以使用new关键字来明确指定要隐藏基类成员的名称和签名。

以下是一个使用new关键字创建新对象的示例代码: 

class MyBaseClass
{
    public void MyMethod()
    {
        Console.WriteLine("MyBaseClass.MyMethod");
    }
}
 
class MyDerivedClass : MyBaseClass
{
    public new void MyMethod()
    {
        Console.WriteLine("MyDerivedClass.MyMethod");
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        MyBaseClass myBaseObject = new MyBaseClass();
        myBaseObject.MyMethod();
 
        MyDerivedClass myDerivedObject = new MyDerivedClass();
        myDerivedObject.MyMethod();
 
        MyBaseClass myDerivedAsBaseObject = new MyDerivedClass();
        myDerivedAsBaseObject.MyMethod();
    }
}

在上面的代码中,定义了一个名为MyBaseClass的基类和一个名为MyDerivedClass的派生类。在MyDerivedClass中,使用new关键字隐藏了基类中的MyMethod方法,并定义了一个新的MyMethod方法。

Main方法中,创建了一个MyBaseClass对象和一个MyDerivedClass对象,并分别调用了它们的MyMethod方法。此外,还创建了一个MyDerivedClass对象,并将其转换为MyBaseClass类型,然后调用了它的MyMethod方法。

除了上面的示例代码中使用的对象创建外,new关键字还可以用于隐藏基类中的字段、属性和事件。在隐藏基类成员时,可以使用new关键字来明确指定要隐藏基类成员的名称和签名。

null 

null关键字,用于表示一个空引用或空对象。在C#中,所有引用类型的变量都可以被赋值为null,表示该变量不引用任何对象。 

以下是一个使用null关键字的示例代码:  

string myString = null;
if (myString == null)
{
    Console.WriteLine("myString is null");
}

在上面的代码中,使用null关键字将一个名为myString的字符串变量初始化为一个空引用。然后,使用if语句检查myString是否为null,如果是,则打印一条消息。 

除了上面的示例代码中使用的变量赋值外,null关键字还可以用于比较引用类型的变量是否为null,以及在方法参数和返回值中使用null表示空引用。

object 

object关键字,它表示所有类的基类。这意味着每个C#类都可以转换为object类型。
object类型是一种通用类型,可以存储任何类型的值,包括值类型和引用类型。 

在C#中,object类型通常用于以下情况: 

  • 当您不知道要存储的值的确切类型时。
  • 当您需要在不同类型之间进行转换时。
  • 当您需要在方法中传递任何类型的参数时。

以下是一些使用object类型的示例: 

object obj1 = "Hello World"; // obj1 is of type object
object obj2 = 123; // obj2 is of type object
object obj3 = new List<int>(); // obj3 is of type object

在上面的示例中,我们可以看到object类型可以存储不同类型的值。

operator 

operator关键字,它用于定义自定义运算符。C#中的运算符可以是算术运算符、比较运算符、逻辑运算符等。使用operator关键字,我们可以定义自己的运算符,以便在我们的代码中使用。 

以下是一些使用operator关键字的示例:  

public static MyClass operator +(MyClass a, MyClass b)
{
    MyClass result = new MyClass();
    result.Value = a.Value + b.Value;
    return result;
}

在上面的示例中,我们定义了一个名为+的运算符,它将两个MyClass对象相加并返回一个新的MyClass对象。我们可以在我们的代码中使用这个运算符,就像使用内置的运算符一样。

out 

out关键字,它用于在方法中传递参数。使用out关键字,我们可以将参数标记为输出参数,这意味着该参数的值将被方法修改并返回。

以下是一个使用out关键字的示例: 

public void Divide(int dividend, int divisor, out int quotient, out int remainder)
{
    quotient = dividend / divisor;
    remainder = dividend % divisor;
}

在上面的示例中,我们定义了一个名为Divide的方法,它接受两个整数作为输入,并使用out关键字将两个整数作为输出参数返回。在方法中,我们计算了两个整数的商和余数,并将它们分别赋值给quotientremainder参数。

在调用Divide方法时,我们需要提供两个整数作为输入参数,并使用out关键字将quotientremainder参数标记为输出参数。方法执行后,quotientremainder参数的值将被修改为计算结果。

override

override关键字,它用于在派生类中重写基类中定义的虚方法。使用override关键字,我们可以在派生类中提供自己的实现,以覆盖基类中的实现。 

以下是一个使用override关键字的示例: 

public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("The animal makes a sound");
    }
}
 
public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("The dog barks");
    }
}

在上面的示例中,我们定义了一个名为Animal的基类和一个名为Dog的派生类。Animal类中定义了一个虚方法MakeSound,它可以被派生类重写。Dog类中使用override关键字重写了MakeSound方法,并提供了自己的实现。

在调用MakeSound方法时,如果我们使用Animal类的实例调用该方法,则会执行Animal类中的实现。如果我们使用Dog类的实例调用该方法,则会执行Dog类中的实现。

params 

params关键字,它用于在方法中传递可变数量的参数。使用params关键字,我们可以将方法的参数列表定义为一个数组,这样我们就可以向方法传递任意数量的参数。 

以下是一个使用params关键字的示例:  

public void PrintNumbers(params int[] numbers)
{
    foreach (int number in numbers)
    {
        Console.WriteLine(number);
    }
}

在上面的示例中,我们定义了一个名为PrintNumbers的方法,它接受一个可变数量的整数作为输入,并使用params关键字将它们定义为一个数组。在方法中,我们使用foreach循环遍历数组,并将每个整数打印到控制台上。

在调用PrintNumbers方法时,我们可以向方法传递任意数量的整数作为参数。这些整数将被打包到一个数组中,并传递给PrintNumbers方法。

private

private关键字,它用于限制类成员的访问权限。使用private关键字,我们可以将类成员标记为私有成员,这意味着只有在同一类中才能访问这些成员。

以下是一个使用private关键字的示例:  

public class MyClass
{
    private int myPrivateField;
 
    private void MyPrivateMethod()
    {
        // do something
    }
}

在上面的示例中,我们定义了一个名为MyClass的类,它包含一个私有字段myPrivateField和一个私有方法MyPrivateMethod。这些成员都使用private关键字标记,这意味着只有在MyClass类中才能访问它们。 

在其他类中,我们无法直接访问MyClass类中的私有成员。如果我们需要访问这些成员,我们可以提供公共方法或属性来访问它们。

protected 

protected关键字,它用于限制类成员的访问权限。使用protected关键字,我们可以将类成员标记为受保护的成员,这意味着只有在同一类或其派生类中才能访问这些成员。 

以下是一个使用protected关键字的示例: 

public class MyClass
{
    protected int myProtectedField;
 
    protected void MyProtectedMethod()
    {
        // do something
    }
}
 
public class MyDerivedClass : MyClass
{
    public void MyDerivedMethod()
    {
        myProtectedField = 42;
        MyProtectedMethod();
    }
}

在上面的示例中,我们定义了一个名为MyClass的类,它包含一个受保护的字段myProtectedField和一个受保护的方法MyProtectedMethod。这些成员都使用protected关键字标记,这意味着只有在MyClass类或其派生类中才能访问它们。

我们还定义了一个名为MyDerivedClass的派生类,它继承自MyClass类。在MyDerivedClass类中,我们可以访问MyClass类中的受保护成员,因为MyDerivedClass类是MyClass类的派生类。

public 

public关键字,它用于声明类成员的访问级别。使用public关键字,我们可以将类成员标记为公共成员,这意味着它们可以在任何地方被访问。 

以下是一个使用public关键字的示例: 

public class MyClass
{
    public int myPublicField;
 
    public void MyPublicMethod()
    {
        // do something
    }
}

在上面的示例中,我们定义了一个名为MyClass的类,它包含一个公共字段myPublicField和一个公共方法MyPublicMethod。这些成员都使用public关键字标记,这意味着它们可以在任何地方被访问。

在其他类中,我们可以直接访问MyClass类中的公共成员。如果我们需要访问这些成员,我们可以创建一个MyClass类的实例,并使用点号运算符来访问它们。

readonly 

readonly关键字,它用于声明只读字段。使用readonly关键字,我们可以将字段标记为只读,这意味着它们只能在声明时或在构造函数中进行初始化,并且不能在其他地方进行修改。

以下是一个使用readonly关键字的示例: 

public class MyClass
{
    public readonly int myReadOnlyField;
 
    public MyClass(int value)
    {
        myReadOnlyField = value;
    }
}

在上面的示例中,我们定义了一个名为MyClass的类,它包含一个只读字段myReadOnlyField。这个字段使用readonly关键字标记,这意味着它只能在声明时或在构造函数中进行初始化,并且不能在其他地方进行修改。

MyClass类的构造函数中,我们将myReadOnlyField字段初始化为传入的value值。一旦初始化完成,这个字段就不能再被修改了。

ref 

ref关键字,它用于将变量传递给方法或函数时,将其作为引用传递而不是值传递。使用ref关键字,我们可以在方法或函数中修改传递的变量的值,并将这些更改反映回调用方。 

以下是一个使用ref关键字的示例: 

public class MyClass
{
    public void MyMethod(ref int myRefParam)
    {
        myRefParam = 42;
    }
}
 
public class Program
{
    static void Main(string[] args)
    {
        int myInt = 0;
        MyClass myClass = new MyClass();
        myClass.MyMethod(ref myInt); 
        Console.WriteLine(myInt); // 输出 42
    }
}

在上面的示例中,我们定义了一个名为MyClass的类,它包含一个名为MyMethod的方法。这个方法使用ref关键字标记其参数myRefParam,这意味着它将作为引用传递而不是值传递。

在MyMethod方法中,我们将myRefParam参数的值设置为42。由于myRefParam是作为引用传递的,因此这个更改将反映回调用方。

在Program类的Main方法中,我们创建了一个名为myInt的整数变量,并将其初始化为0。然后,我们创建了一个MyClass类的实例,并调用其MyMethod方法,将myInt变量作为myRefParam参数传递,并使用ref关键字标记。

最后,我们在控制台上输出myInt变量的值,这将输出42,因为MyMethod方法将其更改为了42。

return

return关键字,用于从方法中返回值。使用return关键字可以将方法的执行控制权返回到调用方法的代码,并且可以返回一个值。 

以下是使用return关键字的示例: 

public int Add(int x, int y)
{
    return x + y;
}
 
int result = Add(1, 2);
Console.WriteLine(result); // 输出3

在上面的示例中,Add方法使用return关键字返回两个整数x和y的和。在调用Add方法时,将参数1和2传递给x和y,并将返回值赋给result变量。在Console.WriteLine语句中,将result变量的值输出到控制台。 

需要注意的是,使用return关键字返回值时,必须在方法签名中指定返回类型。

例如,以下代码将导致编译错误:  

public Add(int x, int y)
{
    return x + y;
}
 在上面的示例中,Add方法没有指定返回类型,因此会导致编译错误。

sbyte 

sbyte关键字,用于声明一个有符号的8位整数类型。sbyte类型的取值范围为-128到127。 

以下是使用sbyte关键字的示例: 

sbyte a = 100;
sbyte b = -50;

在上面的示例中,a和b都是sbyte类型的变量。a的值为100,b的值为-50。 需要注意的是,sbyte类型是一个有符号的整数类型,因此可以表示负数。

另外,由于sbyte类型的取值范围比较小,因此在使用sbyte类型时需要注意数据溢出的问题。

sealed 

sealed关键字,用于限制类和方法的继承。使用sealed关键字可以防止其他类继承该类或方法,从而保护类或方法的实现。 

以下是使用sealed关键字的示例: 

 
public sealed class MyClass
{
    // class implementation
}
 
public class MyDerivedClass : MyClass // 编译错误
{
    // class implementation
}

在上面的示例中,MyClass类使用sealed关键字来限制其他类继承它。在定义MyDerivedClass类时,使用MyClass作为基类会导致编译错误,因为MyClass类已经被标记为sealed。 

需要注意的是,sealed关键字只能用于类和方法,不能用于其他成员,如字段或属性。另外,使用sealed关键字标记的类或方法不能被继承或重写,但可以被实例化或调用。

short 

short关键字,用于声明一个有符号的16位整数类型。short类型的取值范围为-32768到32767。 

以下是使用short关键字的示例: 

short a = 10000;
short b = -20000;

在上面的示例中,a和b都是short类型的变量。a的值为10000,b的值为-20000。 

需要注意的是,short类型是一个有符号的整数类型,因此可以表示负数。另外,由于short类型的取值范围比较小,因此在使用short类型时需要注意数据溢出的问题。

sizeof 

sizeof关键字,用于获取指定类型的大小。使用sizeof关键字可以在编译时获取指定类型的大小,而不需要实例化该类型。 

以下是使用sizeof关键字的示例: 

int size = sizeof(int);
Console.WriteLine(size); // 输出4

在上面的示例中,sizeof关键字用于获取int类型的大小,并将结果赋值给size变量。在Console.WriteLine语句中,将size变量的值输出到控制台。 

需要注意的是,sizeof关键字只能用于值类型,不能用于引用类型。另外,sizeof关键字返回的是指定类型的大小,单位为字节。

stackalloc 

stackalloc关键字,用于在堆栈上分配内存。使用stackalloc关键字可以在堆栈上分配指定大小的内存块,而不需要使用new关键字在堆上分配内存。 

以下是使用stackalloc关键字的示例: 

int[] array = new int[100];
fixed (int* p = array)
{
    int* q = stackalloc int[10];
    for (int i = 0; i < 10; i++)
    {
        q[i] = i;
    }
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine(q[i]);
    }
}

在上面的示例中,stackalloc关键字用于在堆栈上分配一个包含10个int类型元素的内存块,并将其赋值给q指针。在for循环中,将q指针指向的内存块中的元素赋值为i。在第二个for循环中,将q指针指向的内存块中的元素输出到控制台。

需要注意的是,stackalloc关键字只能用于值类型,不能用于引用类型。另外,使用stackalloc关键字分配的内存块在方法返回后会自动释放,不需要手动释放。

static 

static关键字,用于声明静态成员。使用static关键字可以将成员声明为与类相关联,而不是与类的实例相关联。 

以下是使用static关键字的示例: 

public class MyClass
{
    public static int Count = 0;
 
    public MyClass()
    {
        Count++;
    }
}
 
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
Console.WriteLine(MyClass.Count); // 输出2

在上面的示例中,MyClass类中声明了一个静态成员Count,用于记录创建的MyClass对象的数量。在MyClass类的构造函数中,每次创建对象时,都会将Count的值增加1。

在Main方法中,创建了两个MyClass对象,并输出了Count的值,结果为2。 

需要注意的是,静态成员是与类相关联的,而不是与类的实例相关联。因此,可以通过类名来访问静态成员,而不需要创建类的实例。另外,静态成员在程序启动时就会被初始化,并且只会被初始化一次。

string 

string关键字,用于表示字符串类型。使用string关键字可以声明一个字符串变量,并对其进行赋值和操作。 

以下是使用string关键字的示例: 

string str1 = "Hello";
string str2 = "World";
string str3 = str1 + " " + str2;
Console.WriteLine(str3); // 输出"Hello World"

在上面的示例中,string关键字用于声明三个字符串变量str1、str2和str3。在第三行中,使用+运算符将str1、空格和str2连接起来,并将结果赋值给str3。在Console.WriteLine语句中,将str3的值输出到控制台。 

需要注意的是,string类型是引用类型,而不是值类型。因此,声明的字符串变量实际上是一个指向字符串对象的引用。

另外,string类型的字符串是不可变的,也就是说,一旦创建了一个字符串对象,就不能修改它的值。如果需要修改字符串的值,可以使用StringBuilder类。

struct 

struct关键字,用于声明结构体类型。使用struct关键字可以定义一个包含多个字段的值类型,类似于类但有一些不同之处。 

以下是使用struct关键字的示例: 

public struct Point
{
    public int X;
    public int Y;
 
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}
 
Point p = new Point(10, 20);
Console.WriteLine(p.X); // 输出10

在上面的示例中,struct关键字用于声明一个名为Point的结构体类型,包含两个int类型的字段X和Y。在Point结构体的构造函数中,使用传入的参数对X和Y进行初始化。

在Main方法中,创建了一个Point结构体对象p,并输出了X的值,结果为10。 

需要注意的是,结构体是值类型,而不是引用类型。因此,声明的结构体变量实际上是一个包含结构体字段的内存块。另外,结构体变量在创建时会自动初始化为默认值,而不需要手动初始化。

switch 

switch是C#中的关键字之一,用于控制程序流程。它通常与case一起使用,用于比较一个变量或表达式的值与一系列可能的值,并根据匹配的值执行相应的代码块。 

以下是switch语句的基本语法: 

switch (expression)
{
    case value1:
        // code block
        break;
    case value2:
        // code block
        break;
    ...
    default:
        // code block
        break;
}

expression是要比较的变量或表达式,value1,value2等是可能的值。如果expression的值与某个case的值匹配,则执行相应的代码块。如果没有匹配的case,则执行default代码块(如果存在)。 

需要注意的是,每个case代码块必须以break语句结束,否则程序将继续执行下一个case代码块,直到遇到breakdefault为止。 

以下是一个简单的示例,演示了如何使用switch语句:  

int day = 4;
string dayName;
 
switch (day)
{
    case 1:
        dayName = "Monday";
        break;
    case 2:
        dayName = "Tuesday";
        break;
    case 3:
        dayName = "Wednesday";
        break;
    case 4:
        dayName = "Thursday";
        break;
    case 5:
        dayName = "Friday";
        break;
    case 6:
        dayName = "Saturday";
        break;
    case 7:
        dayName = "Sunday";
        break;
    default:
        dayName = "Invalid day";
        break;
}
 
Console.WriteLine("Today is " + dayName);

在这个例子中,switch语句比较day的值与1到7之间的可能值,并根据匹配的值输出。

this

this是C#中的关键字之一,用于引用当前对象。它通常用于区分局部变量和实例变量,或者在构造函数中调用另一个构造函数。 

以下是this关键字的用法示例: 

1. 引用实例变量 

class MyClass
{
    private int myVar;
 
    public MyClass(int myVar)
    {
        this.myVar = myVar;
    }
}

在这个例子中,this.myVar引用了类的实例变量myVar,以区分它和构造函数参数myVar。 

2. 调用另一个构造函数 

class MyClass
{
    private int myVar;
 
    public MyClass() : this(0)
    {
    }
 
    public MyClass(int myVar)
    {
        this.myVar = myVar;
    }
}

在这个例子中,第一个构造函数调用了第二个构造函数,使用this关键字来传递参数。 

需要注意的是,this关键字只能在实例方法和构造函数中使用,不能在静态方法中使用。 

throw 

throw是C#中的关键字之一,用于抛出异常。它通常用于在程序执行过程中发生错误时,向调用方报告错误信息。 

以下是throw关键字的用法示例: 

public void DoSomething(int value)
{
    if (value < 0)
    {
        throw new ArgumentException("Value cannot be negative", "value");
    }
 
    // do something
}

在这个例子中,如果value小于0,则抛出一个ArgumentException异常,其中包含错误信息和参数名称。

需要注意的是,throw关键字只能在方法中使用,不能在属性或索引器中使用。另外,抛出的异常必须是System.Exception或其派生类的实例。 

以下是一个更复杂的示例,演示了如何使用try-catch-finally语句处理异常: 

try
{
    // do something
}
catch (ArgumentException ex)
{
    Console.WriteLine("Argument exception: " + ex.Message);
}
catch (Exception ex)
{
    Console.WriteLine("Exception: " + ex.Message);
}
finally
{
    // cleanup code
}

在这个例子中,try代码块中的代码可能会抛出异常。如果抛出ArgumentException异常,则执行第一个catch代码块,打印错误信息。

如果抛出其他类型的异常,则执行第二个catch代码块,打印错误信息。无论是否发生异常,都会执行finally代码块中的代码,用于清理资源。 

true 

true是C#中的布尔型字面量之一,表示真值。它通常用于比较和逻辑运算中,例如if语句和while循环。 

以下是true关键字的用法示例: 

bool isTrue = true;
 
if (isTrue)
{
    Console.WriteLine("This is true");
}

在这个例子中,isTrue变量被赋值为true,然后在if语句中使用。由于isTrue的值为true,所以if语句中的代码块将被执行,打印"This is true"。 

需要注意的是,true关键字只能表示真值,不能表示其他类型的值。另外,truefalse是C#中的保留字,不能用作标识符或变量名。

try 

try是C#中的关键字之一,用于捕获异常。它通常用于在程序执行过程中发生错误时,处理错误信息。 

以下是try关键字的用法示例: 

try
{
    // do something
}
catch (ArgumentException ex)
{
    Console.WriteLine("Argument exception: " + ex.Message);
}
catch (Exception ex)
{
    Console.WriteLine("Exception: " + ex.Message);
}
finally
{
    // cleanup code
}

在这个例子中,try代码块中的代码可能会抛出异常。如果抛出ArgumentException异常,则执行第一个catch代码块,打印错误信息。

如果抛出其他类型的异常,则执行第二个catch代码块,打印错误信息。无论是否发生异常,都会执行finally代码块中的代码,用于清理资源。 

需要注意的是,try关键字只能在方法中使用,不能在属性或索引器中使用。另外,try语句必须包含至少一个catch块或一个finally块,或者同时包含两者。如果没有catch块或finally块,则编译器会报错。 

另外,try-catch-finally语句可以嵌套使用,以处理更复杂的异常情况。

在嵌套的try-catch-finally语句中,内部的try语句必须包含至少一个catch块或一个finally块,或者同时包含两者。如果没有catch块或finally块,则内部的try语句会向外部的try语句传递异常。

typeof

typeof是C#中的关键字之一,用于获取类型信息。它通常用于在程序运行时获取类型信息,例如在反射中使用。 

以下是typeof关键字的用法示例: 

Type type = typeof(string);
Console.WriteLine(type.FullName);

在这个例子中,typeof关键字用于获取string类型的信息,并将其赋值给type变量。然后,FullName属性用于获取类型的完全限定名称,并将其打印到控制台上。 

需要注意的是,typeof关键字只能用于获取类型信息,不能用于创建类型的实例。另外,typeof关键字只能用于获取编译时已知的类型信息,不能用于获取运行时动态生成的类型信息。 

另外,C#中还有一个GetType方法,可以用于获取对象的类型信息。与typeof关键字不同的是,GetType方法可以用于获取运行时动态生成的类型信息。以下是GetType方法的用法示例: 

string str = "Hello, world!";
Type type = str.GetType();
Console.WriteLine(type.FullName);

在这个例子中,GetType方法用于获取str对象的类型信息,并将其赋值给type变量。然后,FullName属性用于获取类型的完全限定名称,并将其打印到控制台上。

uint 

uint是C#中的关键字之一,表示无符号整数类型。它通常用于需要处理非负整数的情况,例如计数器和索引。 

以下是uint关键字的用法示例:

uint count = 0; 
while (count < 10)
{
    Console.WriteLine(count);
    count++;
}

在这个例子中,count变量被赋值为0,然后在while循环中使用。由于count的值小于10,所以while循环中的代码块将被执行,打印count的值并将其递增。当count的值达到10时,循环结束。 

需要注意的是,uint关键字只能表示非负整数,不能表示负数。另外,uintint是不同的类型,不能直接进行赋值或比较。如果需要将uint类型的值转换为int类型的值,可以使用显式类型转换,

例如: 

uint u = 10;
int i = (int)u;

在这个例子中,u变量被赋值为10,然后使用显式类型转换将其转换为int类型的值,并将其赋值给i变量。

ulong 

ulong是C#中的关键字之一,表示无符号长整数类型。它通常用于需要处理非负长整数的情况,例如计数器和索引。 

以下是ulong关键字的用法示例: 

ulong count = 0; 
while (count < 10)
{
    Console.WriteLine(count);
    count++;
}

在这个例子中,count变量被赋值为0,然后在while循环中使用。由于count的值小于10,所以while循环中的代码块将被执行,打印count的值并将其递增。当count的值达到10时,循环结束。 

需要注意的是,ulong关键字只能表示非负长整数,不能表示负数。另外,ulonglong是不同的类型,不能直接进行赋值或比较。如果需要将ulong类型的值转换为long类型的值,可以使用显式类型转换,

例如: 

ulong u = 10;
long l = (long)u;

在这个例子中,u变量被赋值为10,然后使用显式类型转换将其转换为long类型的值,并将其赋值给l变量。

unchecked 

unchecked 关键字,用于指示编译器在进行算术运算时不进行溢出检查。默认情况下,C# 编译器会在进行算术运算时检查是否会发生溢出,如果会发生溢出则会抛出 System.OverflowException 异常。
使用 unchecked 关键字可以禁用这种检查。 

以下是一个示例,展示了使用 unchecked 关键字进行整数溢出运算的情况: 

int a = int.MaxValue;
int b = unchecked(a + 1);
Console.WriteLine(b); // 输出 -2147483648

在上面的示例中,a 的值为 int 类型的最大值,即 2147483647。由于 a + 1 会导致整数溢出,因此如果不使用 unchecked 关键字,程序会抛出 System.OverflowException 异常。

但是由于使用了 unchecked 关键字,程序会继续执行,b 的值为 -2147483648。 

需要注意的是,使用 unchecked 关键字可能会导致程序出现意外的结果,因此在使用时需要谨慎。如果不确定是否需要使用 unchecked 关键字,建议不要使用,以避免出现意外的结果。

unsafe 

unsafe 关键字,用于指示编译器在进行代码块中的操作时不进行安全检查。默认情况下,C# 编译器会在进行代码块中的操作时检查是否会发生不安全的操作,
如果会发生不安全的操作则会抛出 System.Security.VerificationException 异常。使用 unsafe 关键字可以禁用这种检查。 

以下是一个示例,展示了使用 unsafe 关键字进行指针操作的情况: 

unsafe
{
    int[] arr = new int[10];
    fixed (int* p = arr)
    {
        for (int i = 0; i < 10; i++)
        {
            *(p + i) = i;
        }
    }
}

在上面的示例中,使用 unsafe 关键字声明了一个代码块,其中使用了指针操作。fixed 关键字用于固定数组 arr 的地址,使得指针 p 可以指向数组的首地址。在循环中,使用指针 p 对数组进行了赋值操作。 

需要注意的是,使用 unsafe 关键字可能会导致程序出现不安全的操作,因此在使用时需要谨慎。如果不确定是否需要使用 unsafe 关键字,建议不要使用,以避免出现不安全的操作。

ushort 

ushort 关键字,用于声明一个无符号的 16 位整数类型。与 short 类型相对应,ushort 类型的取值范围为 0 到 65535。 

以下是一个示例,展示了使用 ushort 关键字声明变量的情况: 

ushort a = 65535;
ushort b = 1;
ushort c = (ushort)(a + b);
Console.WriteLine(c); // 输出 0

在上面的示例中,a 和 b 的值分别为 ushort 类型的最大值和 1。由于 a + b 会导致整数溢出,因此 c 的值为 0。 

需要注意的是,使用 ushort 关键字可能会导致程序出现意外的结果,因此在使用时需要谨慎。如果不确定是否需要使用 ushort 关键字,建议根据具体情况进行选择。

using 

using关键字,用于在程序中引入命名空间或者释放资源。 

引入命名空间

在C#中,命名空间用于组织和管理代码,避免命名冲突。使用using

关键字可以在程序中引入命名空间,使得在代码中可以直接使用该命名空间中的类型和成员,而不需要每次都使用完整的命名空间路径。 

例如,如果要使用System.Console类输出信息,可以在代码文件的顶部使用using System;语句引入System命名空间,然后在代码中直接使用Console.WriteLine()方法输出信息,而不需要每次都写出完整的命名空间路径。

释放资源

在C#中,一些对象需要手动释放资源,例如文件、数据库连接等。使用using关键字可以自动释放这些对象占用的资源,避免资源泄露和程序崩溃。 

例如,如果要读取一个文件的内容,可以使用System.IO.File类的ReadAllText()方法。但是在读取完毕后,需要手动调用Dispose()方法释放文件占用的资源。使用using关键字可以自动释放资源,代码如下:

using System.IO;
 
string path = "path/to/file.txt";
using (StreamReader reader = new StreamReader(path))
{
    string content = reader.ReadToEnd();
    Console.WriteLine(content);
}

在上面的代码中,使用using关键字创建了一个StreamReader对象,并在代码块结束时自动调用了Dispose()方法释放资源。

除了引入命名空间和释放资源,using关键字还可以用于其他一些场景。 

别名

使用using关键字可以为类型或命名空间创建别名,方便在代码中使用。例如,可以使用以下语句为System.Console类创建别名Console 

using Console = System.Console; 

然后就可以在代码中直接使用Console.WriteLine()方法输出信息,而不需要写出完整的命名空间路径。

静态类

在C# 6.0及以上版本中,可以使用using static关键字引入静态类的成员,使得在代码中可以直接使用该静态类的成员,而不需要使用类名限定符。 

例如,可以使用以下语句引入System.Math静态类的成员: 

using static System.Math;

然后就可以在代码中直接使用Abs()Sin()等方法,而不需要使用Math类名限定符。 

virtual

virtual关键字,用于定义虚方法。 

虚方法

在C#中,方法可以被重写,即在子类中重新定义一个与父类中同名、同参数列表的方法。但是,如果在父类中定义的方法是非虚方法,那么在子类中重写该方法时,只能使用new关键字隐藏父类中的方法,而不能真正地重写该方法。

如果在父类中定义的方法是虚方法,那么在子类中重写该方法时,可以使用override关键字真正地重写该方法。同时,子类中也可以使用base关键字调用父类中的虚方法。 

例如,可以在父类中定义一个虚方法GetInfo(),然后在子类中重写该方法: 

class Animal
{
    public virtual void GetInfo()
    {
        Console.WriteLine("This is an animal.");
    }
}
 
class Dog : Animal
{
    public override void GetInfo()
    {
        base.GetInfo();
        Console.WriteLine("This is a dog.");
    }
}

在上面的代码中,Animal类中定义了一个虚方法GetInfo(),然后Dog类中重写了该方法,并使用base关键字调用了父类中的虚方法。当调用Dog类的GetInfo()方法时,会先输出"This is an animal.",然后再输出"This is a dog."。

虚属性

除了虚方法,C#中还有虚属性。虚属性是一种可以被重写的属性。使用virtual关键字可以定义虚属性。 

例如,可以在父类中定义一个虚属性Name,然后在子类中重写该属性: 

class Animal
{
    public virtual string Name { get; set; }
}
 
class Dog : Animal
{
    private string _name;
 
    public override string Name
    {
        get { return _name; }
        set { _name = value + " (dog)"; }
    }
}

在上面的代码中,Animal类中定义了一个虚属性Name,然后Dog类中重写了该属性,并在set访问器中添加了一些逻辑。当设置Dog类的Name属性时,会在原有的值后面添加"(dog)"。 

虚索引器

除了虚属性,C#中还有虚索引器。虚索引器是一种可以被重写的索引器。使用virtual关键字可以定义虚索引器。 

例如,可以在父类中定义一个虚索引器this[int index],然后在子类中重写该索引器:

class Animal
{
    public virtual string this[int index]
    {
        get { return "Animal " + index; }
    }
}
 
class Dog : Animal
{
    public override string this[int index]
    {
        get { return "Dog " + index; }
    }
}

在上面的代码中,Animal类中定义了一个虚索引器this[int index],然后Dog类中重写了该索引器。当使用Dog类的索引器时,会返回"Dog "加上索引值。 

void 

void关键字,用于表示一个方法没有返回值。 

在C#中,方法可以有返回值,也可以没有返回值。如果一个方法没有返回值,就可以使用void关键字来表示。例如,下面的代码定义了一个没有返回值的方法PrintHello() 

public void PrintHello()
{
    Console.WriteLine("Hello!");
}

在上面的代码中,PrintHello()方法没有返回值,因此使用了void关键字来表示。 

需要注意的是,如果一个方法有返回值,就不能使用void关键字来表示。例如,下面的代码定义了一个有返回值的方法Add() 

public int Add(int a, int b)
{
    return a + b;
}

在上面的代码中,Add()方法有返回值,因此没有使用void关键字来表示。

volatile 

volatile关键字,用于表示一个字段是易变的,即可能被多个线程同时访问和修改。 

在多线程编程中,如果一个字段被多个线程同时访问和修改,就可能会出现数据不一致的问题。这是因为多个线程可能会同时读取和修改同一个字段,导致数据出现错误。

为了解决这个问题,可以使用volatile关键字来表示一个字段是易变的。这样,编译器就会生成特殊的代码来保证多个线程访问和修改该字段时的正确性。 

例如,下面的代码定义了一个使用volatile关键字的字段counter 

class Counter
{
    private volatile int counter = 0;
 
    public void Increment()
    {
        counter++;
    }
 
    public int GetCounter()
    {
        return counter;
    }
}

在上面的代码中,counter字段被定义为volatile,表示它是易变的。当多个线程同时调用Increment()方法时,会对counter字段进行自增操作。由于counter字段是易变的,因此编译器会生成特殊的代码来保证多个线程访问和修改该字段时的正确性。

需要注意的是,volatile关键字只能保证字段的可见性和有序性,不能保证原子性。如果需要保证原子性,可以使用lock关键字或Interlocked类等其他方式来实现。

while 

while关键字,用于表示一个循环语句。while循环会在条件为真的情况下重复执行一段代码块,直到条件为假为止。 

例如,下面的代码定义了一个使用while关键字的循环: 

int i = 0;
while (i < 10)
{
    Console.WriteLine(i);
    i++;
}

在上面的代码中,while关键字后面的条件是i < 10,表示只要i的值小于10,就会重复执行循环中的代码块。循环中的代码块会输出i的值,并将i的值加1,直到i的值不再小于10为止。 

需要注意的是,如果循环条件一直为真,就会导致无限循环。因此,在使用while循环时,需要确保循环条件最终会变为假,否则程序会一直执行下去。

posted @ 2023-04-06 09:41  新*  阅读(101)  评论(1编辑  收藏  举报