-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API proposal: Nullable.RefValue, RefValueOrDefault #1534
Comments
To ensure that the implementation does not to incur any copies either, I believe the HasValue property would need to be marked |
What if we put this on the existing public static class MemoryMarshal
{
public static ref T GetNullableValueRef(ref Nullable<T> value);
} It just returns a ref to the underlying _value field. No checks are performed. If we put it on that type, it would be one of the few completely type-safe APIs on that class. It's type-safe because even though the value of any given |
Sounds good. If needed, all the other variants could be easily implemented using |
I should correct my earlier statement: it wouldn't be completely type-safe because it would allow creation of a "null" |
I suggest we simply do: namespace System
{
public static class Nullable
{
+ public static ref readonly T GetValueRefOrDefaultRef<T>(in T? nullable) where T : struct => ref nullable.value;
}
} Everything else can be built on top of that: if you want the unsafety of a For naming, it mirrors both Putting it as a static on |
cc @Sergio0694 re: #64491 |
Ah, well I swear this issue hadn't showed up when I tried searching before opening #64491, I'm sorry for the duplicate 😅 The new proposal Stephen mentioned seems perfect, it's all we need anyway to then build on top of it. |
Taking this via in might lead to unexpected results due to unintentionally allowing rvalues to be captured. See related discussion in #31170, where we opted to take a parameter as ref to avoid this possibility, even though we weren't mutating the value. |
Can you share an example? |
class SomeClass
{
public int? SomeProperty { get; set; }
}
SomeClass c = new SomeClass() { SomeProperty = 42 };
ref readonly int theRef = ref Nullable.GetValueRef(c.SomeProperty);
c.SomeProperty = 84;
Console.WriteLine(theRef); // "42" In #31170 there was a proposal for a "thou shalt not pass rvalues to this API" analyzer. That didn't really go anywhere at the time. But presumably that analyzer would be a way to bridge the pit of failure if we decide that such a pit really does exist here. |
namespace System
{
public static partial class Nullable
{
public static ref readonly T GetValueRefOrDefaultRef<T>(in T? nullable) where T : struct;
}
} |
That seems to be solving a specific problem though. Consider that a similar problem exists when I think a more encompassing feature might be something like an attribute along the lines of |
With respect to naming, I think that Ideas:
|
This was all discussed in the API review meeting and the proposed name was still considered the least bad option. |
EDIT: @stephentoub's proposal update from #1534 (comment) on 1/29/2022:
namespace System { public static class Nullable { + public static ref readonly T GetValueRefOrDefaultRef<T>(in T? nullable) where T : struct => ref nullable.value; } }
Proposed API
These parallel the Value property and the GetValueOrDefault methods of
Nullable<T>
, but return the value by reference. They're extension methods because of CS8170: Struct members cannot return 'this' or other instance members by reference.They're useful for accessing the value wrapped by a
Nullable<T>
without incurring a copy.Reference implementation
The text was updated successfully, but these errors were encountered: