Вход | Регистрация
    1  2

Гуру-тест для программистов 1С по C#, на сообразительность.

Гуру-тест для программистов 1С по C#, на сообразительность.
Я
   Гений 1С
 
15.01.21 - 13:13
Итак, нужен рефакторинг кода.

Есть много кода, вида:

if (cond1)
{  struct_A r;
   r.field1 = "aга";
   r.field2 = false;
} else
if (cond2)
{  struct_B r;
   r.field1 = "aга";
   r.field2 = false;
} else
{  struct_C r;
   r.field1 = "aга" + "мухоха"; //иногда код отличается для некоторых структур
   r.field2 = false;
}



Я придумал в итоге, как сделать красиво. Жду ваших гипотез.

ООП (классы) не применял - из тушки по воробьям, считаю.
Макросы нельзя в c#, увы.

Но есть одно хитрое решение! ;-)
   Serginio1
 
101 - 16.01.21 - 16:46
   Serginio1
 
102 - 16.01.21 - 16:48
Ну и передача параметров по ссылке in,ref,out
https://docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/keywords/in-parameter-modifier
   Ненавижу 1С
 
103 - 16.01.21 - 16:49
(98) Ошибка    CS8168    Невозможно вернуть по ссылке локальный "r", так как это не локальная переменная ref    ConsoleApp10    C:\Users\User\source\repos\ConsoleApp10\ConsoleApp10\Program.cs    15
   Кирпич
 
104 - 16.01.21 - 16:54
(102) Так а как можно вернуть ссылку на стековую переменную. Это же глюк. Получается боксится
   Кирпич
 
105 - 16.01.21 - 16:54
(103) Чота не правильно написал наверное
   Кирпич
 
106 - 16.01.21 - 16:55
или С# старый
   Ненавижу 1С
 
107 - 16.01.21 - 16:57
(105) я копировал, а не писал. Шарп новый
   Serginio1
 
108 - 16.01.21 - 16:58
(103) ref struct только для .Net Standard 2.1 .То есть только для Core. Для .Net Framework не доступен.
   Serginio1
 
109 - 16.01.21 - 16:59
   Кирпич
 
110 - 16.01.21 - 17:00
(103) Извини, братан. Я просто здесь пробую. Хрен знает чо там за C# Ж))
https://www.onlinegdb.com/online_csharp_compiler
   Кирпич
 
111 - 16.01.21 - 17:04
(108) Так ссылка на что здесь возвращается? На стековую переменную или таки создается копия этой переменной в куче и уже на нее возвращется ссылка?

static ref XXX xxx() {
    XXX r;
    return ref r;
}

   Кирпич
 
112 - 16.01.21 - 17:04
А ну щас несколько раз вызову
   Serginio1
 
113 - 16.01.21 - 17:07
(111) А как ты думаешь? Что такое передача по ссылке?
ref, out, in 

Method(ref int param);

Для проверки присвой разным переменным и измени
   Serginio1
 
114 - 16.01.21 - 17:08
и посмотри какое значение в реальном объекте
   Ненавижу 1С
 
115 - 16.01.21 - 17:09
(110) это не настоящий: Mono 5.10.1.20 (tarball Thu Mar 29 10:48:35 UTC 2018)
   Кирпич
 
116 - 16.01.21 - 17:10
(115) Ааааа. Так может это просто баг у них такой
   Кирпич
 
117 - 16.01.21 - 17:12
(114) Я знаю что такое по ссылке. Меня смущает, что ссылка на стековую переменную, которая станет мусором при выходе из xxx()
   Serginio1
 
118 - 16.01.21 - 17:12
(115) Попробуй на .Net 5
   Ненавижу 1С
 
119 - 16.01.21 - 17:16
(118) я и попробовал на нем:

static ref XXX xxx() {
    XXX r;
    return ref r;//<<вот так нельзя локальную переменную вернуть CS8168    
}
   Кирпич
 
120 - 16.01.21 - 17:18
Интересно это баг в Mono или у них там реально боксит
   Serginio1
 
121 - 16.01.21 - 18:03
https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/classes-and-structs/ref-returns

Для классса прокатывает
public  class TestRef
    {
        int i;

        public ref int RefProperty { get { return ref i; } }

        public ref int GetRefProperty()
        {
            return ref i;
        }
    }

 Для struct чеhез Span

public ref struct TestRefStruct
    {
        int i;
        //var array = new byte[100];

        Span<byte> arraySpan// = new Span<byte>(array);
        public ref byte RefProperty { get { return ref arraySpan[0]; } }

      
    }

или расширения
https://overcoder.net/q/495043/почему-метод-структуры-c-не-может-вернуть-ссылку-на-поле-а-метод-не-являющийся
   Serginio1
 
122 - 16.01.21 - 18:13
Из комментариев
Документация» ( github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/… ) гласит, что «поля структуры экземпляра безопасны для возврата до тех пор, пока получатель безопасен для возврата». Здесь приёмник (параметр foo ) безопасен для возврата (потому что in ), поэтому, кажется, работает как задумано. В то время как первый случай покрыт "this", небезопасно возвращаться из членов структуры ".
   Кирпич
 
123 - 17.01.21 - 08:48
Можно структуру в массив запихнуть.
        static ref XXX xxx()
        {
            XXX[] x = { new XXX() };
            return ref x[0]; 
        }

Получается почти как в Mono
 
static ref XXX xxx() {
    XXX r;
    return ref r;
}

   Гений 1С
 
124 - 17.01.21 - 09:08
Все бы решилось если бы в C# были бы генераторы статического кода, то бишь макросы, как в Си, было бы намного красивее и без извращений:

MULTICOND
  Cond1 {struct_A r;}  
  Cond2 {struct_B r;}) 
GENERAL
{
   r.field1 = "aга";
   r.field2 = false;
}
   Кирпич
 
125 - 17.01.21 - 09:15
(124) А почему нельзя просто функцию написать и копипастить её вызов?
   Ненавижу 1С
 
126 - 17.01.21 - 10:37
(124) макросы это зло
Генераторы кода есть
   Гений 1С
 
127 - 17.01.21 - 10:46
(126) зло не зло, а тут красивее через генераторы кода (макросы).
(125) потому что типы разные.
   Ненавижу 1С
 
128 - 17.01.21 - 10:53
(127) правильнее через интерфейсы
   Конструктор1С
 
129 - 17.01.21 - 10:53
   Конструктор1С
 
130 - 17.01.21 - 10:55
 
 Рекламное место пустует
   Ненавижу 1С
 
131 - 17.01.21 - 10:57
(127) нужна статья про кризис-айти в виде отсутствия макросов в шарпе
   Кирпич
 
132 - 17.01.21 - 11:02
(127) "типы разные"
ну ты тип как параметр тоже используй
   Гений 1С
 
133 - 17.01.21 - 11:09
(132) нельзя, язык не поддерживает
   Ненавижу 1С
 
134 - 17.01.21 - 11:11
(133) передавать как параметр так себе идея. Но тип Type там есть из коробки

Рано тебе ещё гуру-тесты создавать
   Гений 1С
 
135 - 17.01.21 - 11:12
(134) и как Type поможет?
   Ненавижу 1С
 
136 - 17.01.21 - 11:14
(135) тебе никак. Забудь. Я кстати за адаптер и интерфейс, а не интроспекцию
   Гений 1С
 
137 - 17.01.21 - 11:18
(136) вот видишь, макрос проще решает эту проблему
   Кирпич
 
138 - 17.01.21 - 11:27
(137) покажи макрос для С++, который решит такую задачу
   Ненавижу 1С
 
139 - 17.01.21 - 11:30
(137) не вижу. Костыли это
   Serginio1
 
140 - 17.01.21 - 11:37
(123) Да только XXX[] x = { new XXX() }; это уже объект. Не то
(124) Ты не поверишь, но уже есть
Introducing C# Source Generators
https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/
https://blog.jetbrains.com/dotnet/2020/11/12/source-generators-in-net-5-with-resharper/
https://github.com/dotnet/roslyn/blob/master/docs/features/source-generators.md
   Кирпич
 
141 - 17.01.21 - 11:39
(140) Массив объект? Ну наверное. А структура в массиве не объект же?
   Ненавижу 1С
 
142 - 17.01.21 - 11:42
(141) массив это точно объект. Класс Array
Структура нет. Мне интересно подсчет таких ссылок тоже используется, чтобы объект раньше времени не финализировался?
   Кирпич
 
143 - 17.01.21 - 11:43
static ref XXX xxx()
   {
       return ref (new XXX[1])[0]; 
   }


Так вот еще можно
   Ненавижу 1С
 
144 - 17.01.21 - 11:47
(143) ты уже проверяешь на тру-компиляторе?
   Кирпич
 
145 - 17.01.21 - 11:48
(144) ага
   Serginio1
 
146 - 17.01.21 - 11:53
(143) new XXX[1] это массив. Он выделяется в куче. С этим проблем нет.
Проблема в структурах выделяемых на стеке. При этом ref держит ссылку которая уже не валидная, из-за перезаписи стека.
С объектами такой проблемы нет ибо за объектом следит GC и корректирует  ссылки
   Serginio1
 
147 - 17.01.21 - 11:54
(141) Суть в том, что если структура в объекте, то она не на стеке! Смотри 146
   Кирпич
 
148 - 17.01.21 - 11:55
(146) Ну как бы это понятно. Я просто показал пример, как создать в куче структуру и получить на неё ссылку.
   Ненавижу 1С
 
149 - 17.01.21 - 11:58
(147) вопрос. Какая гарантия что объект не уничтожится, если есть ref ссылка на его поле-структуру?
Надо углубиться в то как выглядит внутри ref.
   Serginio1
 
150 - 17.01.21 - 12:12
(149)
https://overcoder.net/q/495043/почему-метод-структуры-c-не-может-вернуть-ссылку-на-поле-а-метод-не-являющийся

Из комментариев
Документация» ( github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/… ) гласит, что «поля структуры экземпляра безопасны для возврата до тех пор, пока получатель безопасен для возврата». Здесь приёмник (параметр foo ) безопасен для возврата (потому что in ), поэтому, кажется, работает как задумано. В то время как первый случай покрыт "this", небезопасно возвращаться из членов структуры ".
   Serginio1
 
151 - 17.01.21 - 12:15
150 То есть через расширения мы можежем вернуть ссылку на член структуры
struct Foo
{
    internal int _x;

    public ref readonly int MemberGetX() => ref _x;
    //                                          ^^^

    // Error CS8170: Struct members cannot return 'this' or other instance members by reference
}
Это приводит к ошибке. Члены CS8170 Struct не могут возвращать "этот" или другие члены экземпляра по ссылке. Тем не менее, выполнение одной и той же функции с использованием метода расширения не вызывает ошибки:

static class FooExtensions
{
    public static ref readonly int ExtensionGetX( this in Foo foo )
    {
        return ref foo._x;
    }
}

var f = new Foo();
        Console.WriteLine( f.X );
        f.GetXRefExtension() = 123;
        Console.WriteLine( f.X );

        // You can also do it without using an extension method, but the caller is required to specify ref:

        FooExtensions.GetXRef( ref f ) = 999;
        Console.WriteLine( f.X );

        /* Output:
         * 0
         * 123
         * 999
         */

То есть виден контекст и ref работает только на вызывающем стеке
   Serginio1
 
152 - 17.01.21 - 14:19
140 + обсуждение и примеры
Introducing C# Source Generators
http://rsdn.org/forum/dotnet/7719189.flat
   PR
 
153 - 17.01.21 - 21:32
Природа очистилась настолько, что с первой страницы ушли почти все темы Гени
  1  2

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.