3 / 2 / 1
Регистрация: 04.02.2023
Сообщений: 34
.NET 8

Переназначение ссылки с помощью оператора ref не работает

24.07.2024, 19:21. Показов 2573. Ответов 29
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую всех. Очень хотелось бы разобраться с данным вопросом, буду рад ответам.
https://learn.microsoft.com/en... t-operator
В данной статье говорится об операторе "ref"(не который используется в параметрах методах, а который служит некоторым псведонимом для ссылки на объект)
Например:
C#
1
2
3
4
5
6
7
8
9
10
class Program
{
    private static void Main(string[] args)
    {
       int i = 10;
       ref var alias = ref i;
       alias = 2000;
       Console.Write(i); //2000
    }
}
Вопрос в следующем. Судя по следующему коду, ссылка pr в методе Main() должна была стать null, так как мы переназначили ссылку в методе на статическое поле с null. Но программа ведет себя совершенно иначе. В чем же дело?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Program
{
    public static Program program;
 
    public void Bar(ref Program pr)
    {
        pr = ref program;
    }
 
    private static void Main(string[] args)
    {
        Program? pr = new();
        pr.Bar(ref pr);
        var b = pr is null;
        Console.WriteLine(b); //false
    }
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.07.2024, 19:21
Ответы с готовыми решениями:

Ссылки в C#: ref и out
всем привет, вопрос глупый состоит в том что код не компилируется .... public void Show() { Console.WriteLine("a: {0}, b:...

Передача ссылки по ссылке (ref)
Вопрос тут такого себе индивидуального характера. Встретился с этим впервые. Подскажите, почему метод Named, работает только тогда...

Программирование с помощью условного оператора и оператора выбора
Нужно решить две задачи. 1. Даны три числа. Определить является ли сумма каких-либо из них положительной. Указание к выполнению:...

29
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,234
22.08.2024, 13:32
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от INexteR Посмотреть сообщение
В частности, для сведения выделения управляемой памяти к минимуму (сокращая нагрузку на сборщик мусора)
А, ясно, я так и думал, что это микрооптимизации.
Еще в 2018-году опубликованной by K.Kokosa известной книге, не требующей рекламы, упоминается про гарантии таких объектов:
- They are never heap allocated
и как следствие,
- No cross-thread synchronization required
Что может быть очень полезным, когда нам нужны такие гарантии.
Btw, 6 лет всего прошло, а книга слегка устарела (появился POH, который не упоминается в книге, поведение на Unix-ах тоже).

Добавлено через 1 минуту
Зато ClrMD упоминается - бомбическая либа..
0
22.08.2024, 14:05

Не по теме:

Цитата Сообщение от IamRain Посмотреть сообщение
Btw, 6 лет всего прошло, а книга слегка устарела
Есть слух что готовится второе издание.

0
22.08.2024, 14:16

Не по теме:


OwenGlendower, я бы ждал объявления в блоге автора: http://tooslowexception.com/
PS: да, увидел, еще пара авторов в кооперативе.

0
22.08.2024, 14:21

Не по теме:

IamRain, в твиттере был пост. Писал не автор, но он репостнул этот твит. Больше ничего не было. Поэтому я и написал - "слух".

0
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
22.08.2024, 17:28
Цитата Сообщение от IamRain Посмотреть сообщение
- No cross-thread synchronization required
Это потому что такие структуры невозможно передавать между потоками?
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,234
22.08.2024, 18:17
Цитата Сообщение от INexteR Посмотреть сообщение
Это потому что такие структуры невозможно передавать между потоками?
Ну да, в этом вся соль. Попробуйте вместо SpinLock-а из вашего же примера подставить любой свой ref struct.
Упаковать в object - нельзя.
Реализовать интерфейс - нельзя.
ref struct появились, насколько я понимаю, из-за необходимости реализовать т.н interior pointer-ы - то есть ссылки не только на ссылочные типы (на MethodTable - MT - структуру объекта, то есть на начало объекта), но и на произвольные участки памяти (поля объектов, элементы массивов).
Соответственно ссылаться можно (помимо unmanaged) - речь про Span-ы уже - на элементы в стеке (либо в регистры), либо на кучу.
Если ссылаемся на стек, то нужна гарантия что pointer не будет жить дольше (outlive) чем сам кусок памяти, на который мы ссылаемся. Отсюда ятп, ребята хорошо подумали, и решили ограничить время жизни только стеком, в котором ref struct был создан.
1
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
22.08.2024, 21:53
IamRain, так понимаю ссылочные структуры ввели ввиду преимущества указателей в безопасном контексте и в предотвращении выделения памяти во многих распространенных ситуациях.
0
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
23.08.2024, 14:55
IamRain, для примера можно написать структуру-перечислитель, функционирующий подобно методу Split объекта string, который не будет выделять память:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public readonly ref struct CharSpanSplitter
{
    private readonly ReadOnlySpan<char> _input;
    public CharSpanSplitter(ReadOnlySpan<char> input) => _input = input;
    public Enumerator GetEnumerator() => new(_input);
    public ref struct Enumerator
    {
        private readonly ReadOnlySpan<char> _input;
        private int wordPos, chars;
        public ReadOnlySpan<char> Current { get; private set; }
        public Enumerator(ReadOnlySpan<char> input)
        {
            _input = input;
            Current = default;
        }
        public bool MoveNext()
        {
            for (int i = wordPos - 1; ++i < _input.Length;)
            {
                if (!char.IsWhiteSpace(_input[i]))
                    chars++;
                else if (chars > 0)
                {
                    Current = _input.Slice(wordPos, chars);
                    wordPos = i;
                    chars = 0;
                    return true;
                }
                else wordPos++;
            }
            if (chars > 0)
            {
                Current = _input.Slice(wordPos, chars);
                wordPos = _input.Length;
                chars = 0;
                return true;
            }
            return false;
        }
    }
}
public static class CharSpanExtensions
{
    public static CharSpanSplitter Split(this ReadOnlySpan<char> input)
    => new(input);
}
1
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,234
23.08.2024, 15:16
INexteR, интересное решение, смотрю, вы повернутый на perf-e.
Главное, чтобы все было к месту. Это как производительность логгеров увеличивать - а надо ли?
GC в Workstation режиме так или иначе будет регулярно заниматься сборкой мусора, хотим мы этого или нет.
Там где реально нужен non-interruptible код - можно попробовать поиграть с GC.TryStartNoGCRegion(...) и/или переключиться в GC Server Mode.
Правдивые числа времени сборки мусора из той же книги:
1. GC в Gen0 - 3ms
2. GC в Gen1 - 6ms
(Итого сборка при Gen1 condemned будет занимать 9ms).
3. GC в Gen2 - 30ms (и это далеко не предел).
Соответственно надо смотреть в зависимости от требований, надо ли нам на этом заморачиваться или нет.
0
 Аватар для INexteR
17 / 16 / 1
Регистрация: 25.01.2023
Сообщений: 468
23.08.2024, 17:42
Цитата Сообщение от IamRain Посмотреть сообщение
вы повернутый на perf-e.
Да не, нет такого. Просто отправил этот пример вдогонку на ваш вопрос
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.08.2024, 17:42
Помогаю со студенческими работами здесь

Как сделать данный код с помощью OUT\REF ???
нужно этот же код, сделать через OUT и REF (методы процедуры) как это сделать ? using System; using System.Collections.Generic; ...

Переназначение линейного входа на микрофонный не работает
Здравствуйте! Розовый задний вход был бесповоротно сломан. Знаю, что можно использовать синий (линейный) вход для замены. Подключила штекер...

Ref string не работает
Совершенно не понял, по каким причинам string даже через ref не хочет меняться (уже странно было то, что ссылочный тип и его значения по...

Не работает ref параметр
Пишет,что не удалось скопировать. Вот код: /* * Created by SharpDevelop. * User: User * Date: 05.02.2016 * Time: 21:40 ...

Как работает ref?
Изучая описание ключевого слова ref я не совсем понял его смысла, я понял что ref равнозначно return принимаемой переменной, то есть ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

Новые блоги и статьи
[golang] Двоичная куча, min-heap
alhaos 20.05.2026
Двоичная куча Двоичная куча — структура данных, которая всегда держит самый важный элемент наготове. Представьте очередь к хилеру в игре, и очередь из игроков в приоритете те у кого меньше. . .
[golang] Breadth-First Search
alhaos 19.05.2026
BFS (Breadth-First Search) — это базовый алгоритм обхода графа в ширину, который поуровнево исследует все связанные вершины. Он начинает с выбранной точки и проверяет всех соседей, прежде чем. . .
[golang] Алгоритм «Хак Госпера»
alhaos 17.05.2026
Алгоритм «Хак Госпера» Хак Госпера (Gosper's Hack) — алгоритм нахождения следующего по величине числа с тем же количеством установленных бит. Придуман Биллом Госпером в 1970-х, опубликован в. . .
Рисование бинарного древа до 6-го колена на js, svg.
russiannick 17.05.2026
<svg width="335" height="240" viewBox="0 0 335 240" fill="#e5e1bb"> <style> <!]> </ style> <g id="bush"> </ g> </ svg> function fn(){ let rost;/ / высота древа let xx=165,yy=210,w=256;
FSharp: interface of module
DevAlt 16.05.2026
Интерфейс модуля F# позволяет управлять доступностью членов, содержащихся в реализации модуля. По-умолчанию все члены модуля доступны: module Foo let x = 10 let boo () = printfn "boo" . . .
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible". . .
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru