C# 编程/关键字
C# 关键字 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
特殊 C# 标识符(上下文关键字) | |||||||||||||||
| |||||||||||||||
上下文关键字(用于查询) | |||||||||||||||
|
抽象类除了已实现的成员外,还可以包含抽象成员。也就是说,虽然抽象类中的一些方法和属性可能已实现,但其他成员(抽象成员)可能已定义其签名,但没有实现。从抽象类派生的具体子类定义这些方法和属性。
as
关键字将对象强制转换为不同的类型。因此,它类似于 TypeA varA
= (TypeA) varB
语法。区别在于,如果对象是不可兼容的类型,则此关键字将返回 null,而前者方法在这种情况下会引发类型转换异常。
base
关键字描述了你希望参考基类以获取所需信息,而不是在当前实例化类中。
base
类是当前实现类继承自的类。在创建没有定义基类的类时,编译器会自动使用 System.Object
基类。
因此,下面的两个声明是等效的。
public class MyClass
{
}
public class MyClass : System.Object
{
}
使用 base 关键字的一些原因是
- 将信息传递给基类的构造函数
public class MyCustomException : System.Exception
{
public MyCustomException() : base() {}
public MyCustomerException(string message, Exception innerException) : base(message,innerException) {}
// ......
}
- 调用基类中的变量,其中新实现的类正在覆盖其行为
public class MyBaseClass
{
protected string className = "MyBaseClass";
}
public class MyNewClass : MyBaseClass
{
protected new string className = "MyNewClass";
public override string BaseClassName
{
get { return base.className; }
}
}
- 调用基类中的方法。当你想在方法中添加内容,但仍保留基础实现时,这很有用。
// Necessary using's here
public class _Default : System.Web.UI.Page
{
protected void InitializeCulture()
{
System.Threading.Thread.CurrentThread.CurrentUICulture =
CultureInfo.GetSpecificCulture(Page.UICulture);
base.InitializeCulture();
}
}
bool
关键字用于字段、方法、属性 和变量声明,以及在 强制转换 和 typeof
操作中,作为 .NET 框架结构 System.Boolean
的别名。也就是说,它表示 true
或 false
的值。与 C++ 不同,C++ 的 布尔 实际上是 整数,C# 中的 bool
是它自己的数据类型,不能转换为任何其他基本类型。
break
关键字用于退出循环或 switch 块。
break
用于循环中
int x;
while (x < 20){
if (x > 10) break;
x++;
}
只要 x 小于 20,while 循环就会递增 x。但是当 x 递增到 10 时,if 语句中的条件变为 true,因此 break 语句导致 while 循环被中断,执行将在闭合括号后继续。
break
用于 switch 块中
int x;
switch (x)
{
case 0:
Console.WriteLine("x is 0");
break;
case 1:
Console.WriteLine("x is 1");
break;
case 2:
// falls through
case 3:
Console.WriteLine("x is 2 or 3");
break;
}
当程序进入 switch 块时,它将搜索为 true 的 case 语句。一旦找到,它将读取所有进一步打印的语句,直到找到 break 语句。在上面的例子中,如果 x
是 0 或 1,控制台将只打印它们各自的值,然后跳出语句。但是,如果 x
的值是 2 或 3,程序将读取相同的后续语句,直到到达 break 语句。为了不向任何阅读代码的人显示对 2 的处理与 3 相同,良好的编程实践是在 falling-through 的 case 后面添加注释,如“falls through”。
byte
关键字用于字段、方法、属性 和变量声明,以及在 强制转换 和 typeof
操作中,作为 .NET 框架结构 System.Byte
的别名。也就是说,它表示一个 8 位无符号整数,其值范围为 0 到 255。
case
关键字通常用于 switch
语句中。
catch
关键字用于识别 语句 或 语句块 以供执行,如果在封闭的 try
块的主体中发生异常。catch 子句位于 try
子句之前,可以选择后跟 finally
子句。
char
关键字用于字段、方法、属性 和变量声明,以及在 强制转换 和 typeof
操作中,作为 .NET 框架结构 System.Char
的别名。也就是说,它表示一个 Unicode 字符,其值范围为 0 到 65,535。
checked
和 unchecked
运算符用于控制整数类型算术运算和转换的溢出检查上下文。它检查是否发生溢出(这是默认设置)。
- 另请参阅
关键字 class
用于声明一个 类。
关键字 const
用于在字段和局部变量声明中使变量为 常量。因此,它与声明它的类或程序集相关联,而不是与类的实例或方法调用相关联。在声明之外为该变量赋值是语法上无效的。
- 进一步阅读
关键字 continue
可用于方法中的任何循环内。它的作用是结束当前循环迭代并进入下一个循环迭代。如果在 for 循环内执行,则会执行循环结束语句(就像正常循环终止一样)。
关键字 decimal
用于字段、方法、属性 和变量声明以及在 强制转换 和 typeof
操作中,作为 .NET Framework 结构 System.Decimal
的别名。也就是说,它表示一个带符号的 128 位十进制数,其值为 0 或一个具有 28 或 29 位精度的十进制数,范围在 到 之间,或者在 到 之间。
关键字 default
可用于 switch
语句或泛型代码中:[1]
参考文献
[edit | edit source]- ↑ "default (C# Reference)". http://msdn.microsoft.com/en-us/: MSDN. Retrieved 2011-08-09.
{{cite web}}
: External link in
(help)|location=
关键字 delegate
用于声明一个 委托。委托是一种编程构造,用于获取对类方法的可调用引用的。
关键字 do
用于标识一个 do ...
循环 的开始。
关键字 double
用于字段、方法、属性 和变量声明以及在 强制转换 和 typeof
操作中,作为 .NET Framework 结构 System.Double
的别名。也就是说,它表示一个 IEEE 754、64 位带符号二进制浮点数,其值为 负 0、正 0、负无穷大、正无穷大、非数 或一个范围在 到 之间,或者在 到 之间。
关键字 else
用于标识 else
子句,它属于 if
语句的一部分,其语法如下:
- if-statement ::= "
if
" "(
" condition ")
" if-body "else
" else-body - condition ::= boolean-expression
- if-body ::= statement-or-statement-block
- else-body ::= statement-or-statement-block
else
子句紧跟在 if-body 之后。当 condition 为 false 时,它提供要执行的代码。将 else-body 设置为另一个 if
语句会创建一个常见的 cascade 结构,包含 if
、else if
、else if
、else if
、else
语句。
using System;
public class IfStatementSample
{
public void IfMyNumberIs()
{
int myNumber = 5;
if (myNumber == 4)
Console.WriteLine("This will not be shown because myNumber is not 4.");
else if(myNumber < 0)
{
Console.WriteLine("This will not be shown because myNumber is not negative.");
}
else if(myNumber%2 == 0)
Console.WriteLine("This will not be shown because myNumber is not even.");
else
{
Console.WriteLine("myNumber does not match the coded conditions, so this sentence will be shown!");
}
}
}
上面的示例只检查 myNumber
是否小于 0,前提是 myNumber
不等于 4。它依次检查 myNumber%2
是否为 0,前提是 myNumber
不小于 0。由于所有条件都不满足,因此它执行最后 else
子句的主体部分。
关键字 enum
用于标识 枚举。
关键字 event
用于声明 事件。
通用
[edit | edit source]当值被隐式转换时,运行时不需要开发人员在代码中进行任何转换,即可将值转换为新类型。
以下示例中,开发人员正在进行显式转换
// Example of explicit casting.
float fNumber = 100.00f;
int iNumber = (int) fNumber;
开发人员告诉运行时:“我知道我在做什么,强制进行此转换。”
隐式转换意味着运行时不需要任何提示即可进行转换。以下是一个示例。
// Example of implicit casting.
byte bNumber = 10;
int iNumber = bNumber;
关键字
[edit | edit source]请注意,开发人员不需要进行任何转换。隐式转换的特别之处在于,转换的上下文是完全无损的,即转换到此类型不会丢失任何信息,因此可以无忧无虑地转换回来。
关键字 explicit
用于创建类型转换运算符,这些运算符只能通过指定显式类型转换来使用。
此结构有助于软件开发人员编写更易读的代码。使用显式转换名称可以清楚地表明正在进行转换。
class Something
{
public static explicit operator Something(string s)
{
// Convert the string to Something
}
}
string x = "hello";
// Implicit conversion (string to Something) generates a compile time error
Something s = x;
// This statement is correct (explicit type name conversion)
Something s = (Something) x;
关键字 extern
指示正在调用的方法存在于 DLL 中。
名为 tlbimp.exe
的工具可以创建包装程序集,使 C# 可以像使用 .NET 程序集一样与 DLL 交互,即使用构造函数实例化它,调用它的方法。
旧的 DLL 不适用于此方法。相反,您必须显式地告诉编译器要调用哪个 DLL、要调用哪个方法以及要传递哪些参数。由于参数类型非常重要,您也可以显式地定义要传递给方法的参数的类型。
以下是一个示例
using System;
using System.Runtime.InteropServices;
namespace ExternKeyword
{
public class Program
{
static void Main()
{
NativeMethods.MessageBoxEx(IntPtr.Zero, "Hello there", "Caption here", 0, 0);
}
}
public class NativeMethods
{
[DllImport("user32.dll")]
public static extern MessageBoxEx(IntPtr hWnd, string lpText, string lpCaption, uint uType, short wLanguageId);
}
}
[DllImport("user32.dll")]
告诉编译器要引用哪个 DLL。Windows 会根据 PATH 环境变量的定义搜索文件,因此它会在失败之前搜索这些路径。
该方法也是静态的,因为 DLL 可能不理解如何“创建”,因为 DLL 可以用不同的语言创建。这允许直接调用该方法,而不是实例化它,然后使用它。
C# 关键字 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
特殊 C# 标识符(上下文关键字) | |||||||||||||||
| |||||||||||||||
上下文关键字(用于查询) | |||||||||||||||
|
关键字 false
是一个 布尔 常量值。
关键字 finally
用于标识 try
-catch
块之后的语句或语句块,无论关联的 try 块是否遇到异常,都会执行,即使在 return 语句之后也会执行。finally 块用于执行清理活动。
关键字 fixed
用于阻止垃圾收集器重新定位变量。您只能在不安全的上下文中使用它。
fixed (int *c = &shape.color) {
*c = Color.White;
}
如果您使用的是 C# 2.0 或更高版本,则 fixed
也可用于声明固定大小的数组。这在创建与 COM 项目或 DLL 交互的代码时很有用。
您的数组必须由以下基本类型之一组成:bool
、byte
、char
、double
、float
、int
、long
、sbyte
、short
、ulong
或 ushort
。
protected fixed int monthDays[12];
关键字 float
用于字段、方法、属性 和变量声明,以及在转换和 typeof
操作中,作为 .NET Framework 结构 System.Single
的别名。也就是说,它表示 IEEE 754、32 位有符号二进制浮点数,其值为负 0、正 0、负无穷大、正无穷大、非数字,或者介于 到 或从 到 之间的数字。
关键字 for
用于标识 for
循环。
关键字 foreach
用于标识 foreach
循环。
// example of foreach to iterate over an array
public static void Main() {
int[] scores = new int [] { 54, 78, 34, 88, 98, 12 };
int total = 0;
foreach (int score in scores) {
total += score;
}
int averageScore = total/scores.Length;
}
关键字 goto
将操作流程返回到它后面的标签。标签可以通过在任何单词后面添加冒号来创建。例如:
thelabel: // This is a label
System.Console.WriteLine("Blah blah blah");
goto thelabel; // Program flow returns to thelabel
使用 `goto` 语句存在很大争议,因为如果滥用,会造成代码跳来跳去,混乱且难以阅读。实际上,它很少有必要使用,因为通常可以使用组织性更好的 for
循环 或 while
循环 来实现相同的效果。
关键字 if
用于标识一个 if
语句,其语法如下:
- if-statement ::= "if" "(" condition ")" if-body ["else" else-body]
- condition ::= boolean-expression
- if-body ::= statement-or-statement-block
- else-body ::= statement-or-statement-block
如果 condition 的值为 true,则执行 if-body。大括号 ("{
" 和 "}") 允许 if-body 包含多个语句。可以选择性地在 if-body 后面紧跟一个
else
子句,用于提供在 condition 为 false 时执行的代码。如果将 else-body 设置为另一个 if
语句,就会形成常见的 if
, else if
, else if
, else if
, else
语句级联。
using System;
public class IfStatementSample
{
public void IfMyNumberIs()
{
int myNumber = 5;
if (myNumber == 4)
Console.WriteLine("This will not be shown because myNumber is not 4.");
else if(myNumber < 0)
{
Console.WriteLine("This will not be shown because myNumber is not negative.");
}
else if(myNumber%2 == 0)
Console.WriteLine("This will not be shown because myNumber is not even.");
else
{
Console.WriteLine("myNumber does not match the coded conditions, so this sentence will be shown!");
}
}
}
在 if
语句中使用的布尔表达式通常包含以下一个或多个运算符:
运算符 | 含义 | 运算符 | 含义 |
---|---|---|---|
< | < | > | > |
== | == | != | != |
<= | <= | >= | >= |
&& | && | || | || |
! | ! |
另请参阅 else
。
通用
[edit | edit source]当隐式转换值时,运行时不需要开发人员在代码中进行任何强制转换,即可将值转换为新的类型。
以下示例中,开发人员正在进行显式转换
// Example of explicit casting.
float fNumber = 100.00f;
int iNumber = (int) fNumber;
开发人员告诉运行时:“我知道我在做什么,强制进行此转换。”
隐式转换意味着运行时不需要任何提示即可进行转换。以下是一个示例。
// Example of implicit casting.
byte bNumber = 10;
int iNumber = bNumber;
请注意,开发人员无需进行任何强制转换。隐式转换的特殊之处在于,转换到的上下文完全无损,即转换到此类型不会丢失任何信息。因此,可以放心地将其转换回原始类型。
关键字
[edit | edit source]关键字 implicit
用于类型定义如何隐式转换。它用于定义无需显式强制转换即可转换到的类型。
例如,让我们考虑一个 `Fraction` 类,它将存储分子(除法运算符上方的数字)和分母(除法运算符下方的数字)。我们将添加一个属性,以便可以将值转换为 float
。
public class Fraction
{
private int nominator;
private int denominator;
public Fraction(int nominator1, int denominator1)
{
nominator = nominator1;
denominator = denominator1;
}
public float Value { get { return (float)_nominator/(float)_denominator; } }
public static implicit operator float(Fraction f)
{
return f.Value;
}
public override string ToString()
{
return _nominator + "/" + _denominator;
}
}
public class Program
{
[STAThread]
public static void Main(string[] args)
{
Fraction fractionClass = new Fraction(1, 2);
float number = fractionClass;
Console.WriteLine("{0} = {1}", fractionClass, number);
}
}
重申一下,隐式转换到的值必须以原始类可以转换回的格式存储数据。如果这不可能,并且范围缩小(例如,将 double
转换为 int
),请使用显式运算符。
关键字 in
用于标识在 foreach
循环 中枚举的集合。
关键字 in
也可用于查询,例如,`'from
item in
dataset'。紧跟在上下文关键字 from
后面的是一个范围变量,代表数据集中的一个项目。要查询的数据集在上下文关键字 in
后面定义。另请参阅 ascending
, descending
, in
, orderby
, select
和 where
。
关键字 int
用于字段、方法、属性 和变量声明,以及在 强制转换 和 typeof
操作中用作 .NET Framework 结构 System.Int32
的别名。也就是说,它表示一个 32 位有符号整数,其值范围为 -2,147,483,648 到 2,147,483,647。
关键字 interface
用于声明一个 接口。接口为程序员提供了一种构造方法,用于创建可以声明但未实现方法、属性、委托、事件和索引器的类型。
良好的编程实践是为接口提供与类不同的名称,这些名称以 I 开头和/或以 ...able 结尾,例如 IRun
或 Runnable
或 IRunnable
。
关键字 internal
是一个 访问修饰符,用于字段、方法 和 属性 声明,以使字段、方法或属性对其封闭程序集 内部。也就是说,它只在实现它的程序集中 可见。
关键字 is
将一个对象与一个类型进行比较,如果它们相同或属于同一“种类”(对象 继承 类型),则返回 true。因此,此关键字用于检查类型兼容性,通常在 强制转换(转换)源类型到目标类型之前,以确保不会抛出类型转换异常。对 null 变量使用 is
始终返回 false。
此代码片段展示了一个示例用法
System.IO.StreamReader reader = new StreamReader("readme.txt");
bool b = reader is System.IO.TextReader;
// b is now set to true, because StreamReader inherits TextReader
关键字 lock
允许代码段独占使用资源,这在多线程应用程序中非常有用。如果代码段尝试锁定某个对象时,该对象已经被锁定,则该代码段的线程将被阻塞,直到对象可用为止。
using System;
using System.Threading;
class LockDemo
{
private static int number = 0;
private static object lockObject = new object();
private static void DoSomething()
{
while (true)
{
lock (lockObject)
{
int originalNumber = number;
number += 1;
Thread.Sleep((new Random()).Next(1000)); // sleep for a random amount of time
number += 1;
Thread.Sleep((new Random()).Next(1000)); // sleep again
Console.Write("Expecting number to be " + (originalNumber + 2).ToString());
Console.WriteLine(", and it is: " + number.ToString());
// without the lock statement, the above would produce unexpected results,
// since the other thread may have added 2 to the number while we were sleeping.
}
}
}
public static void Main()
{
Thread t = new Thread(new ThreadStart(DoSomething));
t.Start();
DoSomething(); // at this point, two instances of DoSomething are running at the same time.
}
}
lock 语句的参数必须是对象引用,而不是值类型。
class LockDemo2
{
private int number;
private object obj = new object();
public void DoSomething()
{
lock (this) // ok
{
...
}
lock (number) // not ok, number is not a reference
{
...
}
lock (obj) // ok, obj is a reference
{
...
}
}
}
关键字 long
用于字段、方法、属性 和变量声明,以及在 强制转换 和 typeof
操作中用作 .NET Framework 结构 System.Int64
的别名。也就是说,它表示一个 64 位有符号整数,其值范围为 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。
关键字 namespace
用于为类、结构和类型声明提供 命名空间。
关键字 new
有两种不同的含义:
- 它是一个运算符,用于请求其参数标识的类的新的实例。
- 它是一个修饰符,用于显式隐藏成员。
例如,请参见下面的代码
public class Car
{
public void go()
{
}
}
Car theCar = new Car(); // The new operator creates a Car instance
int i = new int(); // Identical to … = 0;
public class Lamborghini : Car
{
public new void go() // Hides Car.go() with this method
{
}
}
关键字 null
表示 引用类型变量的空值,即任何从 System.Object
派生的类型变量的空值。在 C# 2.0 中,null
也表示可空 值类型变量的空值。
关键字 object
用于字段、方法、属性 和变量声明,以及在 强制转换 和 typeof
操作中,作为 .NET Framework 结构 System.Object
的别名。也就是说,它表示所有其他 引用类型 派生的基类。在某些平台上,引用的大小为 32 位,而在其他平台上,它为 64 位。
关键字 operator
允许类重载算术运算符和强制转换运算符。
public class Complex
{
private double re, im;
public double Real
{
get { return re; }
set { re = value; }
}
public double Imaginary
{
get { return im; }
set { im = value; }
}
// binary operator overloading
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex() { Real = c1.Real + c2.Real, Imaginary = c1.Imaginary + c2.Imaginary };
}
// unary operator overloading
public static Complex operator -(Complex c)
{
return new Complex() { Real = -c.Real, Imaginary = -c.Imaginary };
}
// cast operator overloading (both implicit and explicit)
public static implicit operator double(Complex c)
{
// return the modulus: sqrt(x^2 + y^2)
return Math.Sqrt(Math.Pow(c.Real, 2) + Math.Pow(c.Imaginary, 2));
}
public static explicit operator string(Complex c)
{
// we should be overloading the ToString() method, but this is just a demonstration
return c.Real.ToString() + " + " + c.Imaginary.ToString() + "i";
}
}
public class StaticDemo
{
public static void Main()
{
Complex number1 = new Complex() { Real = 1, Imaginary = 2 };
Complex number2 = new Complex() { Real = 4, Imaginary = 10 };
Complex number3 = number1 + number2; // number3 now has Real = 5, Imaginary = 12
number3 = -number3; // number3 now has Real = -5, Imaginary = -12
double testNumber = number3; // testNumber will be set to the absolute value of number3
Console.WriteLine((string)number3); // This will print "-5 + -12i".
// The cast to string was needed because that was an explicit cast operator.
}
}
关键字 out
明确指定变量应以 引用方式 传递给方法,并在该方法中设置。使用此关键字的变量在方法调用之前 不能 初始化,以确保开发人员了解其预期效果。使用此关键字要求被调用方法在返回之前使用此修饰符设置变量。使用 out 还要求开发人员即使在调用代码中也要指定关键字,以确保在读取代码的开发人员中易于看到变量的值将在其他地方更改,这在分析程序流程时很有用。
以下是用 out 传递变量的示例。
void CallingMethod()
{
int i;
SetDependingOnTime(out i);
// i is now 10 before/at 12 am, or 20 after
}
void SetDependingOnTime(out int iValue)
{
iValue = DateTime.Now.Hour <= 12 ? 10 : 20;
}
C# 关键字 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
特殊 C# 标识符(上下文关键字) | |||||||||||||||
| |||||||||||||||
上下文关键字(用于查询) | |||||||||||||||
|
关键字 override
用于声明覆盖函数,该函数扩展了具有相同名称的基类函数。
- 进一步阅读
关键字 params
用于描述将一组参数传递给方法的情况,但参数的数量并不重要,因为它们可能会有所不同。由于数量不重要,params
关键字必须是方法签名中的最后一个变量,以便编译器可以在处理 params 之前处理已定义的参数。
以下是在哪里有效和无效的示例。
// This works
public static void AddToShoppingBasket(decimal total, params string[] items)
{
// ....
}
// This works
public static void AddToShoppingBasket(decimal total, int totalQuantity, params string[] items)
{
// ....
}
// THIS DOES NOT WORK <-------------------->
public static void AddToShoppingBasket(params string[] items, decimal total, int totalQuantity)
{
// ....
}
一个很好的例子是 String.Format
方法。 String.Format
方法允许用户传入一个格式化为其要求的字符串,然后传入许多参数以插入字符串中的值。这是一个例子。
public static string FormatMyString(string format, params string[] values)
{
string myFormat = "Date: {0}, Time: {1}, WeekDay: {1}";
return String.Format(myFormat, DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString(), DateTime.Now.DayOfWeek);
}
// Output will be something like:
//
// Date: 7/8/2007, Time: 13:00, WeekDay: Tuesday;
//
String.Format 方法接收了一个字符串,并将 {0}、{1}、{2} 替换为第 1、第 2 和第 3 个参数。如果 params
关键字不存在,则 String.Format()
将需要无限数量的重载才能满足每种情况。
public string Format(string format, string param1)
{
// .....
}
public string Format(string format, string param1, string param2)
{
// .....
}
public string Format(string format, string param1, string param2, string param3)
{
// .....
}
public string Format(string format, string param1, string param2, string param3, string param4)
{
// .....
}
public string Format(string format, string param1, string param2, string param3, string param4, string param5)
{
// .....
}
// To infinitum
关键字 private
用于字段、方法 和 属性 声明,以使字段、方法或属性对其封闭类 私有。也就是说,它在类之外 不可见。
关键字 protected
用于字段、方法 和 属性 声明,以使字段、方法或属性对其封闭类 受保护。也就是说,它在类之外 不可见。
关键字 public
用于字段、方法 和 属性 声明,以使字段、方法或属性对其封闭类 公开。也就是说,它在任何类中都是 可见 的。
关键字 readonly
与 const 关键字密切相关,除了允许使用此修饰符的变量在构造函数中初始化,以及与类实例(对象)而不是类本身相关联之外。
此关键字的主要用途是允许变量根据调用了哪个构造函数来获取不同的值(如果类有多个构造函数),同时仍然确保开发人员知道一旦创建了对象,该值在代码中永远不会被有意或无意地更改。
这是一个示例用法,假设它位于名为 SampleClass
的类中。
readonly string s;
SampleClass()
{
s = "Hello!";
}
关键字 ref
明确指定变量应以 引用方式 传递而不是以 值方式 传递。
开发人员可能希望通过引用传递变量,特别是在 值类型 的情况下。如果通过引用传递变量,实际上只向函数发送一个指针,这会降低方法调用的成本,因为它会涉及大量数据的复制,这是 C# 在通常传递值类型时所做的。
通过引用传递变量的另一个常见原因是让被调用方法修改其值。由于允许这样做,C# 始终强制在方法调用中指定通过引用传递的值,这是许多其他编程语言所没有的。这使读取代码的开发人员可以轻松地发现可能暗示类型的值已在方法中更改的位置,这在分析程序流程时很有用。
通过引用传递值并不意味着被调用方法 必须 修改值;有关此方面,请参见 out 关键字。
通过引用传递要求传递的变量已初始化。
以下是用引用传递变量的示例。
void CallingMethod()
{
int i = 24;
if (DoubleIfEven(ref i))
Console.WriteLine("i was doubled to {0}", i); // outputs "i was doubled to 48"
}
bool DoubleIfEven(ref int iValue)
{
if (iValue%2 == 0)
{
iValue *= 2;
return true;
}
return false;
}
关键字 return
用于从 方法 或 属性 访问器返回执行。如果 方法 或 属性 访问器具有返回类型,则 return
关键字后跟要返回的值。
关键字 sbyte
用于字段、方法、属性 和变量声明,以及在 强制转换 和 typeof
操作中,作为 .NET Framework 结构 System.SByte
的别名。也就是说,它表示一个 8 位有符号整数,其值范围为 -128 到 127。
关键字 sealed
用于指定类不能被继承。以下示例显示了它可能在其中使用的上下文。
public sealed class
{
...
}
注意: sealed
类继承与 Java 中的final
类相同。
关键字 short
用于字段、方法、属性 和变量声明,以及在 强制转换 和 typeof
操作中,作为 .NET Framework 结构 System.Int16
的别名。也就是说,它表示一个 16 位有符号整数,其值范围为 -32,768 到 32,767。
关键字 sizeof
返回对象需要多少字节才能存储。
一个示例用法
int i = 123456;
Console.WriteLine("Storing i, a {0}, requires {1} bytes, or {2} bits.",
i.GetType(), sizeof(i), sizeof(i)*8);
// outputs "Storing i, a System.Int32, requires 4 bytes, or 32 bits."
关键字 stackalloc
用于不安全的代码上下文中,在堆栈上分配内存块。
int* fib = stackalloc int[100];
在上面的示例中,在堆栈上分配了一个大小足以容纳 100 个 int 类型元素的内存块,而不是在堆上;该块的地址存储在指针 fib 中。此内存不受垃圾回收的约束,因此不必固定(通过 fixed)。内存块的生存期仅限于定义它的方法的生存期(无法在方法返回之前释放内存)。
stackalloc
仅在局部变量初始化器中有效。
由于涉及 Pointer
类型,因此 stackalloc
需要不安全的上下文。请参见不安全的代码和指针。
stackalloc
与 C 运行时库中的 _alloca
相似。
注意* - 来自 MSDN
关键字 static
用于将 类 或类成员(方法、属性、字段 或 变量)声明为 静态。声明为 静态 的 类 只有 静态 成员,这些成员与整个类相关联,而不是与类 实例 相关联。
关键字 string
用于字段、方法、属性 和变量声明,以及在 强制转换 和 typeof
操作中,作为 System.String
的别名。也就是说,它表示一个不可变的字符序列。
关键字 struct
用于声明一个 结构体,即一个充当轻量级类的值类型。
关键字 switch
语句是一个控制语句,通过将控制传递到其主体内的 case 语句之一来处理多个选择和枚举。
这是一个 switch 语句的示例
int currentAge = 18;
switch (currentAge)
{
case 16:
Console.WriteLine("You can drive!");
break;
case 18:
Console.WriteLine("You're finally an adult!");
break;
default:
Console.WriteLine("Nothing exciting happened this year.");
break;
}
Console Output You're finally an adult!
关键字 this
在实例方法或实例属性中用于引用当前类实例。也就是说,this
指向调用其包含方法或属性的对象。它也用于定义 扩展方法。
关键字 throw
用于抛出异常对象。
关键字 true
是一个 布尔常量值。因此
while(true)
将创建一个无限循环。
关键字 try
用于标识语句或语句块作为异常处理序列的主体。异常处理序列的主体必须后跟一个
子句、一个 catch
子句或两者。finally
try
{
foo();
}
catch(Exception Exc)
{
throw new Exception ("this is the error message", Exc);
}
关键字 typeof
当传递一个类名时,它返回 System.Type
类的实例。它类似于关键字 sizeof
,因为它返回一个值而不是开始一段代码(块)(参见 if,try,while)。
一个例子
using System;
namespace MyNamespace
{
class MyClass
{
static void Main(string[] args)
{
Type t = typeof(int);
Console.Out.WriteLine(t.ToString());
Console.In.Read();
}
}
}
输出将是
System.Int32
需要注意的是,与 sizeof
不同,只能将类名本身而不是变量传递给 typeof
,如这里所示
using System;
namespace MyNamespace { class MyClass2 { static void Main(string[] args) { char ch; // This line will cause compilation to fail Type t = typeof(ch); Console.Out.WriteLine(t.ToString()); Console.In.Read(); } } }
有时,类将包含它们自己的 GetType()
方法,该方法将类似于,如果不是完全相同,则类似于 typeof
。
关键字 uint
用于字段、方法、属性 和变量声明以及强制转换和 typeof
操作,作为 .NET Framework 结构 System.UInt32
的别名。也就是说,它表示一个 32 位无符号整数,其值范围为 0 到 4,294,967,295。
关键字 ulong
用于字段、方法、属性 和变量声明以及强制转换和 typeof
操作,作为 .NET Framework 结构 System.UInt64
的别名。也就是说,它表示一个 64 位无符号整数,其值范围为 0 到 18,446,744,073,709,551,615。
</noinclude>
关键字 unchecked
在执行整数运算时会阻止溢出检查。它可以用作单个表达式的运算符,也可以用作整个代码块的语句。
int x, y, z;
x = 1222111000;
y = 1222111000;
// used as an operator
z = unchecked(x*y);
// used as a statement
unchecked {
z = x*y;
x = z*z;
}
关键字 unsafe
可用于修改过程或定义使用不安全代码的代码块。如果代码使用“地址 of”(&
)或指针运算符(*
),则该代码是不安全的。
为了让编译器编译包含此关键字的代码,您必须在使用 Microsoft C-Sharp 编译器时使用 unsafe
选项。
class MyClass {
public static void Main() {
int x = 2;
// example of unsafe to modify a code block
unsafe {
DoSomething(&x);
}
}
// example of unsafe to modify a procedure
unsafe static void DoSomething(int *msg) {
Console.WriteLine(*msg);
}
}
关键字 ushort
用于字段、方法、属性 和变量声明以及强制转换和 typeof
操作,作为 .NET Framework 结构 System.UInt16
的别名。也就是说,它表示一个 16 位无符号整数,其值范围为 0 到 65,535。
关键字 using
在 C# 中具有两个完全不相关的含义,具体取决于它是用作指令还是语句。
指令
[edit | edit source]using
作为指令解析非限定类型引用,以便开发人员不必指定完整的命名空间。
例子
using System;
// A developer can now type ''Console.WriteLine();'' rather than ''System.Console.WriteLine()''.
using
还可以为引用类型提供命名空间别名。
例子
using utils = Company.Application.Utilities;
语句
[edit | edit source]using
作为语句会自动调用指定对象的 dispose
。对象必须实现 IDisposable
接口。只要它们是相同类型,就可以在一个语句中使用多个对象。
例子
using (System.IO.StreamReader reader = new StreamReader("readme.txt"))
{
// read from the file
}
// The file readme.txt has now been closed automatically.
using (Font headerFont = new Font("Arial", 12.0f),
textFont = new Font("Times New Roman", 10.0f))
{
// Use headerFont and textFont.
}
// Both font objects are closed now.
关键字 var
可用于在声明变量时代替类型,以允许编译器推断变量的类型。此功能可用于缩短变量声明,尤其是在实例化泛型类型时,并且在使用 LINQ 表达式时也是必需的(因为查询可能会生成非常复杂的类型)。
以下
int num = 123;
string str = "asdf";
Dictionary<int, string> dict = new Dictionary<int, string>();
等效于
var num = 123;
var str = "asdf";
var dict = new Dictionary<int, string>();
var
不会创建“变体”类型;类型只是由编译器推断的。在无法推断类型的场合,编译器会生成错误
var str; // no assignment, can't infer type
void Function(var arg1, var arg2) // can't infer type
{
...
}
注意:Var 不是关键字
关键字 virtual
应用于方法声明以指示该方法可以在子类中被重写。如果未应用 virtual
关键字并且在子类中定义了与父类中相同签名的方法,则父类中的方法将被子类实现隐藏。换句话说,只有使用此关键字才能真正实现函数的 多态性。
注意:与 Java 相比,如果方法是final
,则该方法不是虚拟的。这是由于不同的 设计理念。
关键字 void
用于 方法 签名以声明不返回值的方法。声明为 void
返回类型的方法无法向其包含的任何 return 语句提供任何参数。
例子
public void WorkRepeatedly (int numberOfTimes)
{
for(int i = 0; i < numberOfTimes; i++)
if(EarlyTerminationIsRequested)
return;
else
DoWork();
}
关键字 volatile
用于声明一个变量,该变量可能会随着时间的推移而改变其值,原因是外部进程、系统硬件或另一个并发运行的线程进行了修改。
您应该在成员变量声明中使用此修饰符,以确保无论何时读取该值,您都始终获得变量的最新(最新)值。
class MyClass
{
public volatile long systemclock;
}
此关键字自 .NET Framework 1.1(Visual Studio 2003)起成为 C# 编程语言的一部分。
关键字 while
用于标识一个 while
循环。
C# 特殊标识符
关键字 add
和 remove
允许您在将委托添加到事件或从事件中删除委托时执行代码。其用法类似于属性的 get 和 set 关键字
public event MyDelegateType MyEvent
{
add
{
// here you can use the keyword "value" to access the delegate that is being added
...
}
remove
{
// here you can use the keyword "value" to access the delegate that is being removed
...
}
}
将委托添加到事件时,将执行 add
块中的代码。类似地,将委托从事件中删除时,将执行 remove
块中的代码。
关键字 alias
用于指示外部别名。
当您需要使用同一程序集的多个版本或具有相同完全限定类型名的程序集时,您需要使用 alias
和 extern
关键字为每个版本提供不同的别名。
例子
extern alias AppTools;
extern alias AppToolsV2;
要使用每个版本的类型名,您有运算符 ::
.
例子
AppTools::MainTool tool_v1 = new AppTools::MainTool();
AppToolsV2::MainTool tool_v2 = new AppToolsV2::MainTool();
然而,这仅仅告诉编译器有几个程序集存在类型名称冲突。为了将每个程序集的哪些内容与别名匹配起来,你需要在编译器选项中区分源代码。在 `dotNet` 命令行中,这些选项应该是
/r:AppTools=AppToolsv100.dll /r:AppToolsV2=AppToolsv200.dll
注意:为了让它发挥作用,你需要为编译器提供一个外部程序集(例如,传递 `/r:EXTALIAS=XXX.dll`)并在代码中标识外部别名(例如 `extern alias EXTALIAS;`)
特殊标识符 get
用于声明属性的读访问器。
关键字 global
在某些情况下用于解决标识符之间的歧义。例如,如果类名和命名空间之间存在冲突,你可以使用关键字 global
来访问命名空间
namespace MyApp
{
public static class System
{
public static void Main()
{
global::System.Console.WriteLine("Hello, World!");
// if we had just used System.Console.WriteLine,
// the compile would think that we referred to a
// class named "Console" inside our "System" class.
}
}
}
global
然而在以下情况下不起作用,因为我们的 System
类没有命名空间
public static class System
{
public static void Main()
{
global::System.Console.WriteLine("Hello, World!");
// "System" doesn't have a namespace, so the above
// would be referring to this class!
}
}
特殊标识符 partial
用于允许开发人员从不同的文件构建类,并让编译器生成一个类,将所有部分类组合在一起。这对于将类分成单独的块非常有用。例如,Visual Studio 2005 将窗体的 UI 代码分隔到一个单独的部分类中,这样你就可以分别处理业务逻辑。
特殊标识符 set
用于声明属性的写访问器。
特殊标识符 value
用于属性的写访问器中,代表为属性分配的值。
关键字 where
有两种不同的含义
- 它用于指定泛型类型参数的一个或多个约束。
- 在 LINQ 中,它用于查询数据源并选择或过滤要返回的元素。
关键字 yield
从迭代器返回下一个值或结束迭代。
C# 关键字的参考列表位于 [2]。