Да, есть способ (но он использует небезопасную черную магию).
Сначала отказ от ответственности.
Тот факт, что метод F
не изменяет struct
это только твоя "конвенция".Для компилятора C # struct
, предоставляемый ref
, является полностью изменяемым.
Наличие struct
, предоставленного readonly ref
через in
, говорит компилятору: пожалуйста, убедитесь, что этот struct
не можетбыть мутированным.
Кстати, если вы передаете struct
как in
, вы должны убедиться, что этот struct
объявлен как readonly struct
.В противном случае компилятор создаст защитные копии struct
(подробнее см. здесь .) Это вторая причина, по которой вы обычно не можете передать ссылку readonly struct
на методпринимая struct
на ref
и изменяя его.
Если вы все еще хотите обойти все эти ограничения, вы можете использовать System.Runtime.CompilerServices.Unsafe
NuGet пакет.
В статическом классе Unsafe
есть метод, который может вам помочь:
public static ref T AsRef<T>(in T source);
Вот пример:
void F<T>(ref T t) where T : struct
{
}
void G<T>(in T t) where T : struct
{
F(ref System.Runtime.CompilerServices.Unsafe.AsRef(in t));
}