Я думал, что понял ограничения возвращает ref, а также экранирует области.
Но теперь я нашел дело, и я не понимаю, почему это незаконно. Кажется, что ref return нельзя использовать, если возвращаемое значение исходит от вложенного метода с какими-либо аргументами ref/out.
public static ref T RefReturn<T>()
{
ref T result = ref GetResult<T>(normalParam: default); // compiles
// ref T result = ref GetResult<T>(out bool outParam); // CS8157 at the return statement
// ref T result = ref GetResult<T>(boxedParam: new StrongBox<bool>()); // a suboptimal workaround
// ... code
return ref result;
}
// the bodies below are just dummy examples
private static ref T GetResult<T>(bool normalParam) => ref (new T[1])[0];
// note that this method compiles in itself but unlike in case of the the previous method
// it is illegal to return its result again
private static ref T GetResult<T>(out bool outParam)
{
outParam = true;
return ref (new T[1])[0];
}
// though a ref/out parameter does not work we can mimic something similar without
// making it impossible to return its result from a caller
private static ref T GetResult<T>(StrongBox<bool> boxedParam)
{
boxedParam.Value = true;
return ref (new T[1])[0];
}
Я могу жить с обходным путем, но я не понимаю, как независимый аргумент по ссылке делает это решение вредным. Насколько я знаю, они не должны быть опасны для внутреннего результата рефери; в противном случае сам внутренний метод также должен вызвать некоторую ошибку. Или я ошибаюсь? Что мне не хватает?
Вот приведен живой пример приведенного выше кода.
out bool
— это не то же самое, чтоout bool
локальный; компилятор может доказать безопасность использования первого, но не второго (точнее, он даже не будет пытаться). - person Jeroen Mostert   schedule 07.01.2021static ref int M() { int x = 0; ref int y = ref N(ref x); return ref y;} static ref int N(ref int z) { return ref z; }
(1) Вам ясно, почему это должно быть незаконным? Если нет, сначала проясните это в уме. (2) учитывая, что это должно быть незаконным, где, по вашему мнению, компилятор должен сообщить об ошибке и почему? - person Eric Lippert   schedule 07.01.2021ref T RefReturn<T>(out bool outParam)
. Создайте ответ, если хотите, и я приму его. - person György Kőszeg   schedule 07.01.2021