-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Please add new syntax keyword "ref?" to represent that "ref return" result might be null #16670
Comments
@VSadov |
Given that the answer was, "Not possible. Not, unless something is fundamentally broken," why do you think there would need to be a way to test for |
You can return null as using System;
using System.Runtime.CompilerServices;
class Program
{
static void Main()
{
int[] array = new int[] { 1, 2, 3 };
{
ref int e = ref FindValue(array, 4);
if (!IsNull(ref e)) e = 5;
}
{
ref int e = ref FindValue(array, 3);
if (!IsNull(ref e)) e = 0;
}
foreach (int x in array)
{
Console.WriteLine(x); // 1, 2, 0
}
}
static ref int FindValue(int[] arr, int value)
{
int i;
for (i = 0; i < arr.Length; i++)
{
if (value == arr[i]) return ref arr[i];
}
return ref NullRef<int>();
}
unsafe static ref T NullRef<T>() where T : struct => ref Unsafe.AsRef<T>((void*)0);
unsafe static bool IsNull<T>(ref T r) where T : struct => Unsafe.AsPointer(ref r) == (void*)0;
} |
@ufcpp |
I was propose it once #11552 |
I can see the value in being able to either return either null or a ref. What's the workaround? A marker ref passed in called |
Here is a type representing either null or a ref. using System;
using System.Runtime.CompilerServices;
unsafe struct NullableRef<T>
{
void* _ref;
public NullableRef(ref T r) => _ref = Unsafe.AsPointer(ref r);
public bool IsNull => _ref == (void*)0;
public ref T Reference => ref Unsafe.AsRef<T>(_ref);
}
class Program
{
static void Main()
{
var array = new[] { 1, 2, 3, 4, 5 };
var x = Find(array, 3);
if (!x.IsNull) x.Reference = 0;
var y = Find(array, 6);
if (!y.IsNull) y.Reference = 0;
Console.WriteLine(string.Join(", ", array));
}
static NullableRef<int> Find(int[] array, int value)
{
for (int i = 0; i < array.Length; i++)
{
if (array[i] == value) return new NullableRef<int>(ref array[i]);
}
return default(NullableRef<int>);
}
} |
Returning From the blog post above it sounds very much like this request to be able to work with |
@ufcpp as the |
@benaadams |
I think we should revise what we really want from returning nullable ref (and nullable in general?) In my opinion. What we really want is, we just want to return reference of things that exist. And if not, most of the times, we will write a logic to branch off doing other things that will not touch that thing So I was propose #11552 which I think what we just want is throwing compile error unless we make a branch to not touch it when it is null Which actually the same idea as #5032 about nullable reference type. We could make And that is what we really want out of it. We actually never want NullableRef to wrap things. We actually want branching enforcement, something like |
ref return is a variable, just like a ref parameter. Having underlying managed pointer be I am wondering why the given scenario is a problem with ref returns and was not a problem with ref parameters... It may be worth looking into this scenario if it becomes very common. |
With With So I think it indeed is a bigger issue with |
Issue moved to dotnet/csharplang #497 via ZenHub |
Now the C#7.0 feature "ref return" doesn't allow null as return value, but null as return value is sometimes useful. For example:
The text was updated successfully, but these errors were encountered: