Pull to refresh

Comments 14

И ref, и out по-разному обрабатываются во время выполнения программы, а во время компиляции они обрабатываются одинаково.

И во время выполнения программы они тоже обрабатываются одинаково. Кстати, есть забавный хак: с помощью System.Runtime.CompilerServices.Unsafe.SkipInit<T> можно обойти требование об обязательной инициализации out-параметра в вызываемом методе.

Автор перепутал, во время компиляции они по разному обрабатываются, в out проверка на присвоение в методе есть, в ref - нет

Вся прелесть ref в C# раскрывается в работе с unmanaged code:

	public unsafe struct uv_timer_t
	{
    // для ref можно делать extenstion методы
		public static void Stop(this ref uv_timer_t timerHandleRef)
		{
				var handlePtr = (IntPtr)Unsafe.AsPointer(ref handle);
		}
    
		[DllImport("libuv", CallingConvention = CallingConvention.Cdecl)]
		private static extern int uv_timer_stop(IntPtr handle);
	}


И далее в коде получаете поинтер на uv_timer_t в unmanaged памяти, преобразуете его в ref uv_timer_t и работаете уже почти как с настоящим типизированным объектом, вызываете методы, передаете дальше по стеку итд. Хранить нельзя, можно преобразовать обратно в IntPtr и хранить его.

ref var timerRef = ref Unsafe.AsRef<uv_timer_t>((void*)POINTER_TO_UNMANAGED_MEMORY);

timerRef.Stop(); // extension method на ref переменных работают by ref

myFunc(ref timerRef); // можно передавать в методы, разыменовывать можно, но не нужно :)
Хранить нельзя

А чтобы не было соблазна так делать, объявите типа как ref struct.

Чую, выпускники вашего курса будут заваливать интервью даже на позицию junior...

Это ж надо, так запутать простые объяснения...

По умолчанию параметры передаются в метод по значению.

Это справедливо для value-типов

Ключевое слово out передает аргументы по ссылке. Это очень похоже на ключевое слово ref.

Это как так-то? А в чём разница? (да, там потом есть табличка, но вот прямо тут лажа).

Требования про инициализацию параметров раскрыта неверно. И про двунаправленную передачу тоже фигня написана...

Тема про ref и out для reference типов не раскрыта.

Чую, выпускники вашего курса будут заваливать интервью даже на позицию junior...

Или нет

И что? Индусы пишущие статьи, за редким исключением балбесы набивающие себе стенд чисто для того, чтоб тыкая в свой профиль наняться на позицию пожирнее, и плюсуют их там исключительно такие-же индусы. Уровень их статей как правило ниже плинтуса, о чем говорит и эта статья.

Хочется плюсиков за переводы - переводите статьи нормальных чуваков, а не хрен пойми кого, например по C# вот: https://blog.marcgravell.com/

будут заваливать интервью даже на позицию junior...

чтоб тыкая в свой профиль наняться на позицию пожирнее

Собственно о том и речь, пройдут и наймутся )

>Это справедливо для value-типов

По умолчанию, ссылки на reference-объекты передаются по значению. Явно это имелось в виду. Можно передавать значение ссылки по ссылке, если использовать ref или out.

Оно как бы да, так и есть, но не многие понимают, что это значит и как работает.

А потом удивляются, что написанное в методе 'someStringVar = "42"; ' не работает.

А можно ещё больше всех запутать и вспомнить про in.
Так-то и in, и ref, и out — это абсолютно одно и то же, но с разными ограничениями, накладываемым при компиляции.

Это справедливо для value-типов

Я не особо разбираюсь, но на реальном примере:
void Foo(List<string> strings){
strings= new List<string>();
}
и
void Foo(ref List<string> strings){
strings = new List<string>();
}

будут иметь разное поведение. Как я понимаю это происходит как раз потому что в первом случае так же передается копия ссылки, а во втором - сама ссылка.

Правильно понимаете.

Проблема подобных обучающих материалов в том, что за словами теряется суть. Например то, что выражение "value-типы хранятся в стеке" верно только для локальных переменных, да и то, с уточнениями.

Кроме информационной каши в тексте статьи есть ещё неприятность -- оформление. В таблице ключевое слово языка ref переживает три начертания: ref, Ref, REF. Куда это годится?

Sign up to leave a comment.