Commit 72d6847
msftbot[bot]
Added [Memory|Span]Owner<T>.DangerousGetArray (#3530)
## PR Type
What kind of change does this PR introduce?
- Feature
<!-- - Code style update (formatting) -->
<!-- - Refactoring (no functional changes, no api changes) -->
<!-- - Build or CI related changes -->
<!-- - Documentation content changes -->
<!-- - Sample app changes -->
<!-- - Other... Please describe: -->
## What is the current behavior?
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
There is currently no way to get the underlying `T[]` array from a `MemoryOwner<T>` or `SpanOwner<T>` instance without going through some hoops that are very inconvenient (and which are only possible for `MemoryOwner<T>`). Being able to use the array directly is necessary when working with some older APIs that don't offer a `Span<T>` or `Memory<T>` overload.
## What is the new behavior?
<!-- Describe how was this issue resolved or changed? -->
This PR introduces a new `DangerousGetArray` method that mirrors the `MemoryMarshal.TryGetArray` method and works on `MemoryOwner<T>` and `SpanOwner<T>` instances. I've removed the try pattern since here the types guarantee that the underlying memory store will always be an array. The methods are called `Dangerous___` because using the array is potentially dangerous in case a user keeps the array after disposing the original owner, as it means that that array might've been rented to some other consumer, so using it could lead to unexpected behavior. The methods are not inherently dangerous per se.
## API surface
```csharp
namespace Microsoft.Toolkit.HighPerformance.Buffers
{
public sealed class MemoryOwner<T>
{
public ArraySegment<T> DangerousGetArray();
}
public readonly ref struct SpanOwner<T>
{
public ArraySegment<T> DangerousGetArray();
}
}
```
## Example usage
Suppose we have a `Person` class with `string Name`, `string Surname` and `int Age` properties, and we want to calculate an MD5 hash with the current state of the class. This was originally asked by a user in the C# Discord server ([here](https://discordapp.com/channels/143867839282020352/312132327348240384/766694351383560205)).
```csharp
public static string GetMD5Hash(Person person)
{
using var buffer = new ArrayPoolBufferWriter<byte>();
buffer.Write<char>(person.Name);
buffer.Write<char>(person.Surname);
buffer.Write(person.Age);
using SpanOwner<byte> hash = SpanOwner<byte>.Allocate(16);
using var md5 = MD5.Create();
md5.TryComputeHash(buffer.WrittenSpan, hash.Span, out _);
return BitConverter.ToString(hash.DangerousGetArray().Array!, 0, 16);
}
```
You can see how here we can leverage the new `DangerousGetArray` API to get the underlying array to use with the `BitConverter.ToString` API, which doesn't have an overload accepting a `ReadOnlySpan<byte>`. The same goes for many other existing APIs that only accept an array as input data instead of the new memory APIs.
## PR Checklist
Please check if your PR fulfills the following requirements:
- [X] Tested code with current [supported SDKs](../readme.md#supported)
- [ ] ~~Pull Request has been submitted to the documentation repository [instructions](..\contributing.md#docs). Link: <!-- docs PR link -->~~
- [ ] ~~Sample in sample app has been added / updated (for bug fixes / features)~~
- [ ] ~~Icon has been created (if new sample) following the [Thumbnail Style Guide and templates](https://github.com/windows-toolkit/WindowsCommunityToolkit-design-assets)~~
- [X] Tests for the changes have been added (for bug fixes / features) (if applicable)
- [X] Header has been added to all new source files (run *build/UpdateHeaders.bat*)
- [X] Contains **NO** breaking changesFile tree
4 files changed
+132
-5
lines changed- Microsoft.Toolkit.HighPerformance/Buffers
4 files changed
+132
-5
lines changedLines changed: 43 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
10 | 13 | | |
11 | 14 | | |
12 | 15 | | |
| |||
180 | 183 | | |
181 | 184 | | |
182 | 185 | | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
183 | 200 | | |
| 201 | + | |
184 | 202 | | |
185 | 203 | | |
186 | 204 | | |
| |||
208 | 226 | | |
209 | 227 | | |
210 | 228 | | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
211 | 254 | | |
212 | 255 | | |
213 | 256 | | |
| |||
222 | 265 | | |
223 | 266 | | |
224 | 267 | | |
225 | | - | |
226 | 268 | | |
227 | 269 | | |
228 | 270 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
10 | 13 | | |
11 | 14 | | |
12 | 15 | | |
| |||
143 | 146 | | |
144 | 147 | | |
145 | 148 | | |
146 | | - | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
147 | 159 | | |
148 | 160 | | |
149 | 161 | | |
| |||
157 | 169 | | |
158 | 170 | | |
159 | 171 | | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
160 | 189 | | |
161 | 190 | | |
162 | 191 | | |
| |||
Lines changed: 40 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | 6 | | |
8 | 7 | | |
9 | 8 | | |
| |||
105 | 104 | | |
106 | 105 | | |
107 | 106 | | |
108 | | - | |
| 107 | + | |
109 | 108 | | |
110 | 109 | | |
111 | 110 | | |
| |||
124 | 123 | | |
125 | 124 | | |
126 | 125 | | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
127 | 165 | | |
128 | 166 | | |
Lines changed: 19 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | | - | |
| 63 | + | |
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
82 | 100 | | |
83 | 101 | | |
0 commit comments