24 декабря Архивач восстановлен после серьёзной аварии. К сожалению, значительная часть сохранённых изображений и видео была потеряна. Подробности случившегося. Мы призываем всех неравнодушных помочь нам с восстановлением утраченного контента!

Как вернуть референс?

 Аноним 20/12/23 Срд 03:23:30 #1 №2969825 
Снимок экрана 2023-12-20 012027.png
Снимок экрана 2023-12-20 в 01.20.50.png
Привет двач. Я начал изучать C# (токо слез с С/C++) и хочу понять - а как вернуть адрес переменной в C#?

На скринах я хочу добиться похожего для C# как на С. Кто-нибудь знает как мне стоит правильнее написать?
Аноним 20/12/23 Срд 13:33:58 #2 №2970315 
Ты дебил? Код не скомпилится, так как C# не позволяет возвращать ссылки на локальные переменные
Аноним 20/12/23 Срд 17:10:19 #3 №2970646 
Зачем тебе это? Просто возвращай лист.
Аноним 20/12/23 Срд 18:31:55 #4 №2970748 
>>2970315
Ты дебил? Я поэтому и спрашиваю как написать так, чтобы работало как на С
Аноним 20/12/23 Срд 18:39:26 #5 №2970750 
>>2970646
Чтобы не копировать массив для возвращения, а вернуть указатель на уже выделенную ячейку памяти
Аноним 20/12/23 Срд 20:09:33 #6 №2970833 
>>2970750
>Чтобы не копировать массив для возвращения, а вернуть указатель на уже выделенную ячейку памяти
Так ты и так это сделаешь вернув List. List ссылочный тип и при передаче передается только ссылка на него.
Прочитай про ссылочные и значимые типы в C#
>>2969825 (OP)
>Кто-нибудь знает как мне стоит правильнее написать?
1) Выкинь все ref нахуй (вообще все)
2) В первом if можешь просто написать return new List<int>{0};

Остальное не смотрел, единственное, что - назвавния переменных пиздец, отвыкай так писать.
Аноним 20/12/23 Срд 21:50:41 #7 №2970947 
>>2970833
Я правильно тогда понимаю, что инструкция new как и в С++ возвращает не сам объект, а скорее адрес на созданный объект?

И тогда получается правильно будет интерпретировать

public List<int> f() {
return new List<int>();
}

как

int f() {
return (int
)malloc(sizeof(int));
}

так ведь?

А ref будет тогда использоваться токо в качестве параметра для функций для избежания лишнего копирования данных, так?
Аноним 21/12/23 Чтв 00:16:35 #8 №2971061 
>>2970947
ref это для параметров метода, чтобы можно было их внутри метода поменять, и чтобы это изменение можно было увидеть снаружи.
Это аналог передачи по ссылке.

Тебе надо врубиться в разницу между типами-значениями и типами-ссылками. Загугли и почитай.
Аноним 22/12/23 Птн 15:06:53 #9 №2972839 
1703246812490.jpeg
>>2969825 (OP)
Ты можешь использовать указатели, как в си. Там в настройках проекта надо разрешить небезопасный код и в самом коде перед функцией ключевое слово unsafe написать. Тогда, на сколько помню, всё будет по человечески, как в сях
Аноним 23/12/23 Суб 20:01:51 #10 №2974020 
На самом деле еще орнее чем ОП долбоеб, долбоебский С++ создающий копии коллекций при каждом пуке. И эти опущи рассказывают сказки как они заботятся о производительности.
Аноним 23/12/23 Суб 20:49:50 #11 №2974125 
>>2974020
Я люблю создавать дип копии. Каждый день пишу код с дип копиями. Нужно передать объект в функцию? Я создаю дип копию! Нужно вернуть коллекцию? Я создаю дип копию! Поменять один элемент массива? Ну это же очевидно, надо просто создать дип копию!
Аноним 23/12/23 Суб 21:00:52 #12 №2974136 
>>2969825 (OP)
Личрали:
>у долбоеба забрали дробовик за ненадобностью и чтобы не застрелил себя случайно
>хмм... ребят, а где здесь у вас дробовик можно найти???
Аноним 23/12/23 Суб 21:12:55 #13 №2974152 
>>2969825 (OP)
Ты сначала ошибку в коде справа почиини-то.
Аноним 24/12/23 Вск 17:32:20 #14 №2975450 
image.png
>>2969825 (OP)
Вот так
Аноним 24/12/23 Вск 17:58:38 #15 №2975505 
image.png
>>2975450
А теперь пояснение.

В шарпе - есть ссылочные типы(reference type) и значимые типы(value type).

Классы, рекорды - ссылочные типы.
Структуры - значимые типы.

Семантика простая - для значимых типов ты всегда передаешь копию. Для ссылочных - ты передаешь копию ссылки на объект.

Убедиться в этом можно довольно просто. Например прикриплейд. Массив - в шарпе ссылочного типа. Потому - я могу изменить что-то в массиве и это повлияет на объект который был снаружи.
Но если бы я выполнил присвоение для аргумента, это не повлечет переприсование значения. Потому что передана копия ссылки, а не оригинальная ссылка. Ну, тут думаю понятно.

Дальше.
ref используется, когда в методе тебе прям нужна оригинальная ссылка, например - если метод может переопределить значение по ссылке внутри себя, либо если это структура, которую ты хочешь модифицировать в теле метода(помним, что структуры - значимые, а потому копируются, вот тут работает почти так же как в си/си++).

Например

void foo(ref MyClass a){
if(NotValid(a)) a = new MyClass();
}

В таком случае - передастся не копия ссылки, а оригинальная ссылка на объект, и переприсвоив значение - ты изменишь значение снаружи. Это крайне редко надо, потому.

Для случаев, когда это надо - обычно используется out для аргументов функции. Это более явно и компилятор будет прверять, что ты таки не забыл присвоить значение в теле метода.
Для случаев, когда тебе наоборот - не нужно ничего по ссылке изменять - есть модификатор in, например, тебе для рассчетов надо передавать структуру, ты не будешь ее менять, но не хочешь постоянно копировать - используешь int foo(in MyStruct a, in MyStruct b);

Дополнительно, для сишника надо еще объяснить про упаковку-распоковку. Но уже как-то лень. Да и я хуевый объяснятор.
Аноним 24/12/23 Вск 18:11:27 #16 №2975520 
>>2970947
Неправильно.
new это вызов конструктора. А что он вернет - зависит от того что ты там создал.
Для структуры - он вернет честно шарповскую структуру. Для классов-рекордов - ссылку.

Если тебе так хочется с сишкой ассоциации иметь.

То это что-то в духе

// для класса
some✼ create_some() {
some✼ ptr = malloc(sizeof some);
some_ctor(ptr);
return ptr;
}

// для структуры
some create_some(){
some item = {0};
some_ctor(✼item);
return item;
}
Аноним 27/12/23 Срд 06:11:25 #17 №2979498 
>>2974152
А что у меня там?
Аноним 27/12/23 Срд 06:23:59 #18 №2979503 
>>2975505
Спасибо за объяснение. Это на самом деле многое объясняет, но также и усложняет.

Если базовые идеи in, ref, out по-сути своей работают также как ✷ или & в с/с++ то в чем смысл? Или это своего рода подсказка для компилятора, что вот ты использовал in а значит прописывать машинный код на случай изменения данных не нужно? Типо как подсказки inline или noexcept или constexpr в с++?
Аноним 27/12/23 Срд 06:26:03 #19 №2979504 
>>2974020
Ну-ка расскажи по-подробнее пж
Аноним 27/12/23 Срд 06:48:52 #20 №2979509 
>>2974020
Походу ты вообще ни разу не сидел и не писал ничего на С/С++ и затираешь какую-то херь.

Иди почитай хотя бы про std::move() и учи нормальные языки, а не дичь по типу JavaScript или Python
Аноним 27/12/23 Срд 07:53:40 #21 №2979525 
>>2979503
>Если базовые идеи in, ref, out по-сути своей работают также как ✷ или & в с/с++ то в чем смысл?
Забудь про in, ref, out. Это всё уродливая хуйня, которая больше не нужна.
Теперь есть удобные кортежи, даже с именами, например (int result, string message), которые можно возвращать из методов.
По существу: указатели в C# это исключительно в блоке unsafe. Это надо только там, где у тебя пиздец бутылочное горлышко по производительности.
ref это то же самое, что & в сях
out это если тебе недостаточно вернуть одно значение. Как я написал, для этого теперь есть кортежи.
Аноним 27/12/23 Срд 09:08:14 #22 №2979557 
>>2979525
>Как я написал, для этого теперь есть кортежи.
Хуйню несешь. Взять какой нибудь условный TryParse — этот метод возвращает bool как результат успешности операции, но в out идет результат парсинга. Именно поэтому возможно удобным способом впихнуть метод в качестве условия проверки if, что будет очень геморно с обоссаными кортежами.

if (TryParse(zalupa, out int udobnayaZalupa)){
result = udobnayaZalupa + pizda;
}
Аноним 27/12/23 Срд 10:31:57 #23 №2979602 
>>2979525
>указатели в C# это исключительно в блоке unsafe. Это надо только там, где у тебя пиздец бутылочное горлышко по производительности.
Не только. Если понадобится дергать какие-нибудь нативные библиотеки (например при работе с криптографией) то без этого не обойтись.
Аноним 27/12/23 Срд 21:33:43 #24 №2980439 
>>2969825 (OP)
тебе по-моему здесь реф вообще не нужен, это простейший слуГлинтвейн, просто возвращай sub_list
Аноним 30/12/23 Суб 03:56:36 #25 №2983421 
image.png
image.png
>>2975505
>(a, b) = (b, a)
Аноним 30/12/23 Суб 04:30:08 #26 №2983425 
image.png
image.png
>>2979557
Нахуй ты ньюфагов некроговну учишь? Если бы не обратная совместимость - про out уже давно бы все забыли
Аноним 30/12/23 Суб 06:03:09 #27 №2983430 
>>2983425

j_j ничего не понял из этого синтаксиса
Аноним 30/12/23 Суб 07:28:16 #28 №2983437 
>>2983430
>j_j ничего не понял из этого синтаксиса
Тут много выебонов просто. Суть первого скрина в том, что есть nullable типы, например int?. Он может содержать число или null. Соответственно метод Parse может вернуть null если распарсить не удалось, то есть два значения умещаются в одну переменную.
Ещё у него там метод в виде стрелочной функции, но это к теме отношения не имеет.

На втором скрине новые кортежи, которые объявляются в виде (T1 var1, T2 var2, ...) вместе с деконструкцией. То бишь var1, var2 ит.д. можно использовать вне кортежа как самостоятельные переменные. Кортеж по-английски будет tuple, если погуглить решишь.

Если честно, с моей точки зрения этот сахар уже на грани того, где он вместо повышения читаемости за счёт сокращения кода, будет её понижать из-за изобилия магических значков.
Аноним 30/12/23 Суб 12:56:12 #29 №2983518 
>>2983437
Только кончи возвращают null в качестве идентификатора успеха. Ну или ньюфаки.
Аноним 30/12/23 Суб 13:56:50 #30 №2983550 
>>2983518
>Только кончи возвращают null в качестве идентификатора успеха. Ну или ньюфаки.
Что ты несешь, болезный?
Где ты такое в моём посте прочитал?
Аноним 30/12/23 Суб 14:11:29 #31 №2983567 
>>2983550
В твоем посте описание пикрил 1 >>2983425
>Суть первого скрина в том, что есть nullable типы, например int?. Он может содержать число или null. Соответственно метод Parse может вернуть null если распарсить не удалось, то есть два значения умещаются в одну переменную.
Аноним 30/12/23 Суб 14:49:24 #32 №2983625 
>>2979509
Ну наконец "правильно делай правильно будет"-копиум подъехал.
>std::move()
кривой костыль
Аноним 30/12/23 Суб 17:10:27 #33 №2983795 
>>2983567
>возвращают null в качестве идентификатора успеха
>>2983567
>вернуть null если распарсить не удалось
Анон, ты неправильно читаешь. И такая штука используется повсеместно в стандартной (и не очень) библиотеке 🥗. Тот же FirstOrDefault() абсолютно так же возвращает либо объект, либо default (null)
Аноним 30/12/23 Суб 18:32:17 #34 №2983918 
>>2983795
>Анон, ты неправильно читаешь.
Я имел ввиду идентификацию успешности, которая может быть положительной, так и отрицательной.

>Тот же FirstOrDefault() абсолютно так же возвращает либо объект, либо default (null)
Нет, метод возвращает то, что ты указал. И если ты всунул null в default, то сам виноват. В данном случае обязанности перекладываются с метода на тебя, но это не значит, что ты должен туда засовывать null, иначе смысл данного метода теряется.

В общем и целом такой подход (возврат null ) не является правильным по многим причинам:
а) null может являться нормальным состоянием возвращаемой переменной
б) у типов есть свои кастомные состояния:
- string.Empty
- double.NaN
- Binding.DoNothing
- DependencyProperty.UnsetValue
И эти состояния куда безопаснее. Например возврат пустого массива никак не затронет работоспособность последующего цикла перебора этого массива. Даже если я где-то прощелкаю проверку, это не вызовет исключение.
Именно поэтому существуют методы типа FirstOrDefault(), чтобы ты туда поместил состояние подходящее конкретно для обрабатываемого типа.
в) отсутствие стандарта, из-за чего одни надо проверять на нал, другие на бул, третьи еще как-то. Это может привести к непредвиденным переусложнениям. А булевое значение достаточно примитивное и суперуниверсальное решение. Если уж так хочется, то возвращай кортежи через out.
Аноним 30/12/23 Суб 18:37:45 #35 №2983938 
>>2983918
>иначе смысл данного метода теряется.
Смысл FirstOrDefault() обеспечить бесперебойность работы. Метод должен вернуть любое работающее значение. Например ты читаешь сеттингсы из файла, а в файле данного параметра нет, но ты все равно выводишь дефолтное значение.

Когда ты возвращаешь null, то руинишь саму идею метода (кроме случаев из пункта a), когда null является нормальным состоянием)
Аноним 30/12/23 Суб 19:05:06 #36 №2984011 
>>2983918
а) null не должен являться нормальным состоянием возвращаемой переменной
б) для этого и существуют
- string.Empty
- double.NaN
- Binding.DoNothing
- DependencyProperty.UnsetValue
в) возвращение була это некрокал из 80х, когда это и вместо исключений использовалось. Не надо выносить реализацию в интерфейс
Аноним 30/12/23 Суб 19:35:45 #37 №2984081 
>>2984011
>null не должен являться нормальным состоянием возвращаемой переменной
Но переменная может иметь null в качестве нормального состояния. Тогда возврат null методом в качестве неудачи даст неоднозначность.

>для этого и существуют
Чтобы ты не использовал нал

>возвращение була это некрокал из 80х
Это твое дело. Создание исключение дорогостоящая операция, в отличии от возврата булевого состояния. Вероятно ты не задумываешься о бущуем своего метода. Я не говорю, что исключения не нужны, я говорю о том, что всему есть место. Будучи Белый Медведьом метода FirstOrDefault(), ты уверен в том как и где этот метод будет использоваться? Не будут ли тебя проклинать те, кто будет использовать твой метод, например, в анимации?

Я вот пидорасам, возвращающих исключения в асинхронных методах, желаю исключительно рака. Потому что этот кал не обработать никак.
Аноним 30/12/23 Суб 22:40:06 #38 №2984325 
>>2983625
МЯУ. Лучше все через хер писать. О таких как ты будут вспоминать как о дегенератах с говнокодом.
Аноним 30/12/23 Суб 23:46:43 #39 №2984363 
>>2984081
>Но переменная может иметь null в качестве нормального состояния
Синтаксически? Да. Семантически? Нет.
>Тогда возврат null методом в качестве неудачи даст неоднозначность.
Если для тебя не однозначно что значит null, возвращённый методом, который парсит строку в число, то проблемы с тобой, а не с нуллом.
Аноним 30/12/23 Суб 23:50:37 #40 №2984370 
>>2984363
>Если для тебя не однозначно что значит null, возвращённый методом, который парсит строку в число, то проблемы с тобой, а не с нуллом.

>null на входе
>невалидный UTF-8
>невалидное число
>арифметическое переполнение

Нет, не очевидно.
Мимо проходил
Аноним 30/12/23 Суб 23:55:08 #41 №2984381 
>>2984370
>промазал пальцем
>недостаточно рам
>полетела винда
>умер дед

За корректность введённых данных отвечает юзер, а не Белый Медведь.
Аноним 31/12/23 Вск 01:01:14 #42 №2984425 
Чето посмотрел на тред и прямо порадовался от того как ахуенно у меня в гошечке реализована работа с поинтерами. Извиняюсь не удержался
Аноним 31/12/23 Вск 18:18:34 #43 №2984800 
народ,такая хуйня,внутри редактора юнити игра играется нормально а когда собираю в билд анимации гг ломаются и движется хуй пойми как,кто нибудь знает с чем может быть связанно?
Аноним 31/12/23 Вск 22:12:53 #44 №2985015 
>>2984800
/gd/
Аноним 01/01/24 Пнд 16:37:17 #45 №2985350 
>>2979498
Ты не проверил результат malloc
Аноним 01/01/24 Пнд 19:38:18 #46 №2985507 
>>2985350
В этой тестовой программе мне этого не нужно
Аноним 01/01/24 Пнд 19:40:25 #47 №2985508 
>>2985350
Да и вообще речь не об этом. Контекст треда вообще о другом. Пиши по теме пж.
Аноним 02/01/24 Втр 02:15:44 #48 №2985857 
>>2985507
>>2985508
Так ты сам попросил указать в чем дело
Аноним 02/01/24 Втр 15:46:51 #49 №2986186 
>>2985857
Я думал там будет что-то прям существенно важное связанное с возвращением указателя или с синтаксисом (проблема или предупреждение после компиляции)
Аноним 19/03/24 Втр 07:12:08 #50 №3091743 
>>2970748
Во первых если тебя интересуют адреса, то нужно работать с указателями. А чтобы с ними работать нужно ли компилятор C# глобально настроить с работой небезопасного когда. Либо некий код заключить в unsafe{ некий код}.

Всё нахуй. Дальше же ты С знаешь.

Но в С# нахуй не надо это в целом. Смирись и запомни концепцию значимых и ссылочных типом, так даже проще мыслить когда пишешь C#.
Аноним 20/03/24 Срд 02:01:12 #51 №3093141 
>>2970947
>так ведь?
да, в джаве/шарпе все объекты - это ссылки
Аноним 20/03/24 Срд 02:09:27 #52 №3093153 
>>2970947
Это можно интерпретировать как (для C++)

public List& f() {
return *(new List());
}
comments powered by Disqus

Отзывы и предложения