checked与unchecked:检查一个值在内存中是否有溢出。
C#语言是一种强类型语言。任何一个变量在内存中都是有数据类型的。数据类型有一个非常重要的标识:类型在内存中所占空间的大小。一旦一个变量在内存中超过了它定义的内存空间,是否需要去检查。就要由checked和unchecked来操作。
static void Main(string[] args)
{
uint x = uint.MaxValue;
Console.WriteLine(x);
string binStr = Convert.ToString(x, 2);
Console.WriteLine(binStr);
uint y = x + 1;
Console.WriteLine(y); // y变成了0;内存溢出。
uint z = checked(x + 1);
Console.WriteLine(z);
}
加上checked之后会抛出异常:
System.OverflowException:“Arithmetic operation resulted in an overflow.”
此时需要让catch去接收捕获这个异常。
class Program
{
static void Main(string[] args)
{
uint x = uint.MaxValue;
Console.WriteLine(x);
string binStr = Convert.ToString(x, 2);
Console.WriteLine(binStr);
uint y = x + 1;
Console.WriteLine(y); // y变成了0;内存溢出。
try
{
uint z = checked(x + 1);
Console.WriteLine(z);
}
catch (OverflowException ex)
{
// 一旦捕获这个异常:
Console.WriteLine("There's overflow.");
}
}
}
若改为unchecked,则不再检查。还是直接输出0。
C#默认采用个就是unchecked模式。
checked、unchecked还有一种检测上下文用法
class Program
{
static void Main(string[] args)
{
uint x = uint.MaxValue;
Console.WriteLine(x);
string binStr = Convert.ToString(x, 2);
Console.WriteLine(binStr);
uint y = x + 1;
Console.WriteLine(y); // y变成了0;内存溢出。
checked
{
try
{
uint z = checked(x + 1);
Console.WriteLine(z);
}
catch (OverflowException ex)
{
// 一旦捕获这个异常:
Console.WriteLine("There's overflow.");
}
}
}
}
delegate操作符:
稀有技术,过时了,因为现在更常见的都是用lambda表达式。
匿名方法:
this.myButton.Click += myButton_Click;
void myButton_Click(object sender, RoutedEventArgs e)
{
this.myTextBox.Text = "Hello, World!";
}
通过delegate简写为:
this.myButton.Click +=delegate(object sender, RoutedEventArgs e)
{
this.myTextBox.Text = "Hello, World!";
};
注意最后一个{}后面要写一个分号;,表达一个完整的语句。
上面写法过时了:现在都是写lambda表示式方式。
this.myButton.Click += (sender, e)=>
{
this.myTextBox.Text = "Hello world!";
};
(sender,e)=>{};意思是说,将sender和e这两个变量带入到{}表达式中去。
sizeof:获取一个对象在内存中所占字节数的尺寸。
1、默认情况下:sizeof只能获取基本数据类型的实例在内存中所占的字节数。除了String和Object。因为sizeof只能获取结构体类型数据在内存中的字节数。string和object不是结构体。
// 默认情况下
int x = sizeof(int);// int 4,long 8, ulong 8, double 8;decimal 16;
Console.WriteLine(x);
2、非默认情况下:可以使用sizeof去获取自定义的结构体类型的实例在内存中所占的字节数,需要放在不安全的上下文中。
为了写unsafe的代码,需要突破vs的双保险。
1、在项目中:属性:生成中设置为:允许不安全代码。
2、在代码中声明unsafe。
class Program
{
static void Main(string[] args)
{
// 非默认情况下:
unsafe
{
int x = sizeof(Student);
Console.WriteLine(x); // 16
}
}
}
struct Student
{
int ID;
long Score;
}
->:箭头操作符。通过指针间接访问对象成员。
在C/C++中用指针去访问对象成员。C#也有真正的指针。
直接操作内存,所以必须放在不安全的上下文中。
在C#中明文规定:指针操作、 取地址操作、用指针去访问成员的操作,只能用来操作结构体类型,不能用他们来操作引用类型。
class Program
{
static void Main(string[] args)
{
// 非默认情况下:
unsafe
{
Student stu;
stu.ID = 1;
stu.Score = 99;
Student* pStu = &stu; // &用来取地址。
pStu->Score = 100;
Console.WriteLine(stu.);
}
}
}
struct Student
{
public int ID;
public long Score;
}
凡是通过stu点访问的都是直接访问,而通过pStu箭头号访问的都是通过指针的间接访问。