{"id":17165,"date":"2018-09-17T13:00:00","date_gmt":"2018-09-17T13:00:00","guid":{"rendered":"https:\/\/blog.jetbrains.com\/dotnet\/?p=20384"},"modified":"2019-03-15T13:56:14","modified_gmt":"2019-03-15T13:56:14","slug":"c-sharp-updates-for-stackalloc","status":"publish","type":"dotnet","link":"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2018\/09\/17\/c-sharp-updates-for-stackalloc","title":{"rendered":"C# 7.2 and 7.3 updates for stackalloc"},"content":{"rendered":"<p>The latest versions of\u00a0<a href=\"https:\/\/www.jetbrains.com\/resharper\" target=\"_blank\" rel=\"noopener\">ReSharper 2018.2<\/a>\u00a0and\u00a0<a href=\"https:\/\/www.jetbrains.com\/rider\" target=\"_blank\" rel=\"noopener\">Rider 2018.2<\/a>\u00a0come with support for C# 7.3.\u00a0In this series, we are looking at these\u00a0<strong>new language features in C# 7.3<\/strong>. Today we will look at the <span style=\"color: #000000;\"><b>array\u00a0initializers\u00a0in stackalloc<\/b><\/span>.<\/p>\n<p>This post is part of a series:<\/p>\n<ul>\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/07\/12\/declaration-expressions-in-initializers-and-queries\/\">Declaration expressions in initializers and queries<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/07\/13\/tuple-equality\/\">Tuple equality<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/07\/19\/unmanaged-delegate-enum-type-constraints-c-7-3-rider-resharper\/\">Unmanaged, delegate and enum type constraints<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/07\/24\/ref-local-re-assignment\/\">Ref local re-assignment<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/08\/27\/fixed-pattern\/\">Fixed pattern and simplified access to fixed size buffer elements<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/09\/17\/c-sharp-updates-for-stackalloc\/\">C# updates for stackalloc<\/a><\/li>\n<\/ul>\n<p>In C#, the <code>stackalloc<\/code> keyword is used in an unsafe code context to allocate a block of memory on the stack. The\u00a0<code>stackalloc<\/code>\u00a0operator is similar to the <code>_alloca<\/code> function from the C language. This C# operator is used as a way of manually allocated memory buffers that can be used without type safety checks.<\/p>\n<h2>When do you need to use stackalloc?<\/h2>\n<p>In an average project, you probably won&#8217;t need this. For real-time sensitive scenarios (possibly video or audio), it gives better performance for working with small arrays storing data that is cached locally. In such cases, data is not allocated on the managed heap so no Garbage Collection (GC) is involved &#8211; you are only looking at a call to the unsafe array. Also, remember that <code>stackalloc<\/code> does come with some additional costs with needing to zeroing the allocated memory. If that overhead is too high you can always look at using off-heap solutions for your needs.<\/p>\n<h2>Changes with stackalloc in C# 7.2<\/h2>\n<p>There are several changes around\u00a0<code class=\"inline-code\">stackalloc<\/code>\u00a0that\u00a0were done for C# 7.2. Before C# 7.2 you could only use <code>stackalloc<\/code> as an initializer of local pointer variable and only within unsafe context:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-title=\"\">unsafe void M()\r\n{\r\n    int* array = stackalloc int[1024];\r\n}<\/pre>\n<p>Since C# 7.2, stackalloc is an\u00a0expression and is valid in conditional expressions and assignment expressions outside of unsafe contexts:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-title=\"\">void M(int size)\r\n{\r\n    Span&lt;byte&gt; span = size &lt;= 128 ? stackalloc byte[size] : new byte[size];\r\n    \/\/ ...\r\n    span = stackalloc byte[128];\r\n}<\/pre>\n<p>This example also shows that using <code>stackalloc<\/code> as an expression is now convertible to <code>Span&lt;T&gt;<\/code> type and also <code>ReadOnlySpan&lt;T&gt;<\/code>. Also, that unsafe context is not required when <code>stackalloc<\/code> expression type if converted to <code>Span&lt;T&gt;<\/code> or <code>ReadOnlySpan&lt;T&gt;<\/code>.<\/p>\n<h2>Changes with stackalloc in C# 7.3<\/h2>\n<p>Let&#8217;s look at using the new C# 7.3 feature for initializing arrays with <code>stackalloc<\/code>. Initializing arrays in a safe code context has been around since the inception of C# as in the following:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-title=\"\">var arr = new int[5] {1, 4, 9, 16, 25};\r\nvar arr2 = new int[] {1, 2, 4, 8};\r\nvar arr3 = new float[] {1.1F, 3.2F, 43.7F};<\/pre>\n<p>Using <code>stackalloc<\/code> to create the same arrays would be written as:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-title=\"\">int* pArr = stackalloc int[5] {1, 4, 9, 16, 25};\r\nint* pArr2 = stackalloc int[] {1, 2, 4, 8};\r\nfloat* pArr3 = stackalloc float[] {1.1F, 3.2F, 43.7F};<\/pre>\n<h2>Conclusion<\/h2>\n<p>There have been a number of changes to <code>stackalloc<\/code> that allows the C# operator to be used outside of the unsafe context, in an expression and also now allows for initialization of arrays. With the changes, more developers may find <code>stackalloc<\/code> useful in their solutions when they need to work directly with the stack memory.<\/p>\n<p><a href=\"https:\/\/www.jetbrains.com\/resharper\" target=\"_blank\" rel=\"noopener\"><b>Download ReSharper 2018.2 now!<\/b><\/a>\u00a0Or give\u00a0<a href=\"https:\/\/www.jetbrains.com\/rider\" target=\"_blank\" rel=\"noopener\">Rider 2018.2\u00a0<\/a>a try. We\u2019d love to hear your thoughts!<code><\/code><\/p>\n","protected":false},"author":774,"featured_media":0,"comment_status":"open","ping_status":"open","template":"","categories":[1401],"tags":[211,46,1978],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/17165"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/types\/dotnet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/users\/774"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/comments?post=17165"}],"version-history":[{"count":0,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/17165\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media?parent=17165"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/categories?post=17165"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/tags?post=17165"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/cross-post-tag?post=17165"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}