1 概要
不安全的代码,简单来说就是可以控制内存,就是系统不会自动给你回收内存。说的直白点,就是像c++一样的使用内存和指针。
1.1关于Span
在对内存指定的一段的处理,原来的 C# 是比较弱的,因为没有了 C++ 的指针,特别是对于字符串的分割,需要创建多几个字符串。垃圾微软为了提高 C# 的性能,于是提供了新的类型 Span,这个类可以拿出任意数组的一段,作为一个新的 Span 列表。这样的底层就是指针,而且指针是有判断是否超过范围比 C++ 安全。
2 代码
using System;
using System.Runtime.InteropServices;
namespace 不安全的代码
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
//使用指针.main();
//地址的运算.main();
//基于栈的数组.main();
//Span引用托管堆.main();
//Span引用栈.main();
Span引用本机堆.main();
Console.ReadLine();
}
}
unsafe class 使用指针
{
int* mA;
public static void main()
{
使用指针 a = new 使用指针();
int b = 5;
a.mA = &b;
Console.WriteLine(*a.mA);
int c = (int)a.mA;
Console.WriteLine(c);
}
}
unsafe class 地址的运算
{
public static void main()
{
//变量地址间的距离
int a1 = 0;
int a2 = 0;
Console.WriteLine("a1的地址 :" + (int)(&a1));
Console.WriteLine("a2的地址 :" + (int)(&a2));
Console.WriteLine("a2的地址+1:" + (int)(&a2 + 1));
}
}
unsafe class 基于栈的数组
{
public static void main()
{
int* a = stackalloc int[3];
for(int i = 0; i < 3; i++)
{
a[i] = i;
Console.WriteLine((int)(&a[i]));
}
Console.WriteLine((int)a);
Console.WriteLine("数组地址+2");
for (int i = 0; i < 3; i++)
{
a[i] = i;
Console.WriteLine((int)(&a[i]));
}
Console.WriteLine((int)(a+2));
}
}
class Span引用托管堆
{
public static void main()
{
Span<int> span1 = (new int[] { 1, 6, 7, 8, 2, 5 }).AsSpan();
span1.Slice(start: 2, length: 2).Fill(12);
Console.WriteLine(string.Join(",", span1.ToArray()));
}
}
unsafe class Span引用栈
{
public static void main()
{
long* lp = stackalloc long[20];
var span1 = new Span<long>(lp, 20);
for(int i = 0; i < 20; i++)
{
span1[i] = i;
}
Console.WriteLine(string.Join(",", span1.ToArray()));
}
}
unsafe class Span引用本机堆
{
public static void main()
{
const int nbytes = 100;
IntPtr p = Marshal.AllocHGlobal(nbytes);
try
{
int* p2 = (int*)p.ToPointer();
Span<int> span = new Span<int>(p2, nbytes >> 2);
span.Fill(42);
int max = nbytes >> 2;
for(int i = 0; i < max; i++)
{
Console.Write($"{span[i]}");
}
Console.WriteLine();
}
finally
{
Marshal.FreeHGlobal(p);
}
}
}
}
3 运行效果
使用指针
Hello World!
5
-1057430292
地址的运算
Hello World!
a1的地址 :119334724
a2的地址 :119334720
a2的地址+1:119334724
基于栈的数组
Hello World!
683139088
683139092
683139096
683139088
数组地址+2
683139088
683139092
683139096
683139096
Span引用托管堆
Hello World!
1,6,12,12,2,5
Span引用栈
Hello World!
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
Span引用本机堆
Hello World!
42424242424242424242424242424242424242424242424242
4 环境设置(使用不安全的代码需要对工程环境进行设置)

本文详细探讨了C#中不安全代码的概念及其应用,重点介绍了Span类的特性与使用方法,展示了如何利用指针、栈和本机堆进行内存操作,以及Span在字符串分割和性能优化方面的优势。
2683

被折叠的 条评论
为什么被折叠?



