C# 语言不常用方法、运算符和技巧
在这里,我将对 .NET 2.0/1.1 中包含的一些内容进行基本概述,但只有少数开发人员在使用它们。我并不是说没有人知道这些函数、运算符或功能,而是只有少数开发人员根据他们的需求使用它们。
引言
过去两年里,我一直在担任软件开发人员,从事各种 .NET 技术的工作。我使用过 .Net 1.1 和 .NET 2.0。最近,我们将项目从 .NET 1.1 迁移到 2.0。Visual Studio 2005 提供了许多新功能。在这里,我将对 .NET 2.0/1.1 中包含的一些内容进行基本概述,但只有少数开发人员在使用它们。我并不是说没有人知道这些函数、运算符或功能,而是只有少数开发人员根据他们的需求使用它们。
checked 和 unchecked 运算符
考虑以下代码:
byte b = 255;
b++;
Console.WriteLine (b.ToString ());
byte 数据类型只能保存 0 到 255 范围内的值,因此递增 b 的值会导致溢出。CLR 如何处理此问题取决于许多因素,包括编译器选项,因此每当存在意外溢出的风险时,您都需要某种方法来确保获得所需的结果。
为此,C# 提供了 checked 和 unchecked 运算符。如果将代码块标记为 checked,则 CLR 将强制执行溢出检查,并在发生溢出时抛出 `OverflowException`。让我们更改代码以包含 checked 运算符。
byte b = 255;
checked
{
b++;
}
Console.WriteLine (b.ToString ());
尝试运行此代码时,您将收到如下错误消息。
Unhandled Exception: System.OverflowException: Arithmetic operation resulted in an
Overflow.
at Demo.DemoCSharp.OverflowTest.Main(String[] args)
如果要禁止溢出检查,可以将代码标记为 unchecked,如下所示。
byte b = 255;
unchecked
{
b++;
}
Console.WriteLine (b.ToString ());
在这种情况下,您将丢失数据,但不会引发异常。
可空类型和运算符
在 C# 2005 中,由于泛型的缘故,现在可以使用 `System.Nullable<T>` 创建可空值类型。
要创建 `int` 的可空类型,我们可以使用此语法。
System.Nullable<int> x = new System.Nullable<int>;
有一种新的类型修饰符可用于以下方式创建可空类型。
int? a =null;
int? b= a + 4;
int?c = a +5;
空合并运算符
空合并运算符 (??) 提供了一种简写机制,用于在处理可空类型和引用类型时处理可能出现的 null 值。该运算符位于两个操作数之间——第一个操作数必须是可空类型或引用类型,第二个操作数必须与第一个操作数类型相同,或者可以隐式转换为第一个操作数类型的类型。它的计算结果如下:如果第一个操作数不是 null,则整个表达式的值为第一个操作数;但是,如果第一个操作数是 null,则整个表达式的值为第二个操作数。例如
int? a =null;
int b;
b=a??10; // b has value 10
a=5;
b=a??10; //b has value 5
as 运算符
此运算符用于执行引用类型的显式类型转换。如果要转换的类型与指定的类型兼容,则转换成功完成;否则,此运算符返回 null 值。
object o1 ="my string";
object o2 =25;
string str1= o1 as string; //str1="my string"
string str2 = o2 as string; //str2=null
预处理器 #warning 和 #error
这些将分别导致编译器遇到它们时发出警告或错误。
例如
#if DEBUG && RELEASE
#error "You have defined DEBUG & RELEASE simultaneously."
#end if
#warning "Don't forget to remove this line before setup."
Console.WriteLine(" Some message");
ReferenceEquals() 方法
`ReferenceEquals()` 是一个 `static` 方法,用于测试两个引用是否引用类的同一实例;具体来说,是两个引用是否包含内存中的同一地址。作为一个 `static` 方法,它是无法重写的,因此 `System.Object` 实现就是您始终拥有的。如果提供两个引用同一个对象实例的引用,`ReferenceEquals()` 将始终返回 `true`,否则返回 `false`。但是,它认为 null 等于 null。
SomeClass x, y;
x = new SomeClass();
y = new SomeClass();
bool B1 = ReferenceEquals(null, null); // returns true
bool B2 = ReferenceEquals(null,x); // returns false
bool B3 = ReferenceEquals(x, y); // returns false because x and y
// point to different objects
另一点是,当应用于值类型时,`ReferenceEquals()` 始终返回 `false`,因为要调用此方法,值类型需要装箱到对象中。即使你写…
bool b = ReferenceEquals(v,v); // v is a variable of some value type
…你仍然会得到 `false` 的答案,因为在转换每个参数时,v 将被单独装箱,这意味着您得到了不同的引用。调用 `ReferenceEquals()` 来比较值类型实际上没有多大意义。
历史
- 2007 年 5 月 4 日:初始发布