Путаница здесь потому, что в отличие от указателей (как в *), «реф» в C# не является частью типа, а является частью сигнатуры метода. Он применяется к параметру и означает, что «это нельзя копировать». Это не означает, что «этот аргумент имеет ссылочный тип».
Параметр, переданный ref, вместо представления нового места хранения, является псевдонимом некоторого существующего местоположения. Как создается псевдоним, технически является детальностью реализации. Чаще всего псевдонимы реализуются как управляемые ссылки, но не всегда. В некоторых связанных с асинхронными случаями, например, ссылка на элемент массива может быть внутренне представлена как комбинация массива и индекса.
По существу для всех целей ваши a и b все еще понимаются C# в качестве типизированных переменных. Это законно и совершенно нормально использовать их в любом выражении, которое принимает значения int, такие как a + b или SomeMethod (a, b), и в этих случаях используются фактические значения int, хранящиеся в a и b.
На самом деле нет понятия «ссылки» как объекта, с которым вы можете напрямую работать с C#. В отличие от указателей, предполагается, что фактические значения управляемых ссылок могут быть изменены в любой момент или даже асинхронно с помощью GC, поэтому набор значимых сценариев для управляемых ссылок будет крайне ограниченным.
потому что ссылки не похожи для типов значений. –
Модификатор 'ref' не вызывает привязку соответствующего аргумента к ссылочному типу. – Lee
Вы пытаетесь увидеть, являются ли эти два параметра ссылками на одну и ту же переменную? – BoltClock