一、前言
其實說到ref,很多同學對它已經有所了解,ref是C# 7.0的一個語言特性,它為開發人員提供了返回本地變量引用和值引用的機制。
Span也是建立在ref語法基礎上的一個復雜的數據類型,在文章的后半部分,我會有一個例子說明如何使用它。
二、ref關鍵字
不論是ref還是out關鍵,都是一種比較難以理解和操作的語言特性,如C語言中操作指針一樣,這樣的高級語法總是什么帶來一些副作用,但是我不認為這有什么,而且不是每一個C#開發者都要對這些內部運行的機制有著深刻的理解,我覺得不論什么復雜的東西只是為人們提供了一個自由的選擇,風險和靈活性永遠是不能兼容的。
來看幾個例子來說明引用與指針的相同性,當然下面的使用方式早在C# 7.0之前就可以使用了:
public static void IncrementByRef(ref int x){ x++;}public unsafe static void IncrementByPointer(int* x){ (*x)++;}上面兩個函數分別是使用ref和非安全指針來完成參數+1。
int i = 30;IncrementByRef(ref i);// i = 31unsafe{ IncrementByPointer(&i);}// i = 32下面是C# 7.0提供的特性:
1.ref locals (引用本地變量)
int i = 42;ref var x = ref i;x = x + 1;// i = 43
這個例子中為本地 i 變量的引用 x, 當改變x的值時i變量的值也改變了。
2.ref returns (返回值引用)
ref returns是C# 7中一個強大的特性,下面代碼是最能體現其特性的,該函數提供了,返回int數組中某一項的引用:
public static ref int GetArrayRef(int[] items, int index) => ref items[index];
通過下標取得數組中的項目的引用,改變引用值時,數組也會隨之改變。
三、Span
System.Span是.Net Core核心的一部分,在System.Memory.dll 程序集下。目前該特性是獨立的,將來可能會集成到CoreFx中;
如何使用呢?在.Net Core 2.0 SDK創建的項目下引用如下NuGet包:
<ItemGroup> <PackageReference Include="System.Memory" Version="4.4.0-preview1-25305-02" /> <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.4.0-preview1-25305-02" /> </ItemGroup>
在上面我們看到了使用ref關鍵字可以提供的類似指針(T*)的操作單一值對象方式?;旧显?NET體系下操作指針都不認為是一件好的事件,當然.NET為我們提供了安全操作單值引用的ref。但是單值只是用戶使用“指針”的一小部分需求;對于指針來說,更常見的情況是操作一系列連續的內存空間中的“元素”時。
Span表示為一個已知長度和類型的連續內存塊。許多方面講它非常類似T[]或ArraySegment,它提供安全的訪問內存區域指針的能力。其實我理解它更將是.NET中操作(void*)指針的抽象,熟悉C/C++開發者應該更明白這意味著什么。
新聞熱點
疑難解答
圖片精選