Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
2 / 2 / 1
Регистрация: 12.06.2022
Сообщений: 44

Кортежи. Преобразование типов

07.07.2022, 23:20. Показов 2651. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Хочу заставить такую конструкцию работать:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MyClass
 {
        public static MyClass Test()
       {
               retrun new MyClass();
 
       }
 
        public void Deconstruct(out object v0, out object v1)
        {
            v0 = 1;
            v1 = 2;
        }
 }
 
(int x, int y) = MyClass.Test();
Я хочу что бы функция возвращала переменное количество объектов, при этом каждый объект мог иметь различный тип. Для этого я возвращаю кортеж. Для декомпозиции кортежа - я сделал свою функцию. Собственно я сделаю Deconstruct для разного количества возвращаемых параметров. В данном примере 2 параметра. Т.к. тип развращаемых параметров будет разный то я взял тип object.

Так вот это - (int x, int y) = MyClass.Test(); ругается что мол не может неявно преобразовать тип (object, object) в тип (int, int). Пишет сделайте явное приведение. И вот тут я что то не понял как сделать это. перепробовал кучу вариантов - всё не так.

Можно сделать так:
C#
1
var (x, y) = MyClass.Test();
Но тогда типы x, y - остаются object.

Или такое извращение:
C#
1
2
var res = (_,_) = MyClass.Test();
(int x, int y) = ((int, int))res;
тоже работает. Hо это изврат. Хочу в одну строку. Кто знает как это сделать?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.07.2022, 23:20
Ответы с готовыми решениями:

Преобразование типов
Подскажите, пожалуйста! Я не сильна в C#. Я ввожу в textBox любое отрицательное число. Преобразовала в double таким оразом: private...

Преобразование типов данных
Есть допустим 3 неких объекта (их может быть и тысячи), у них есть параметр " дата " (число когда они были созданы) при создании...

Преобразование типов в обобщенном методе
Всем доброго времени суток. public static void Metod<T>(T a1) where T: struct // Какое поставить ограничение, чтобы можно было...

35
2 / 2 / 1
Регистрация: 12.06.2022
Сообщений: 44
11.07.2022, 16:30  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Dr9vik Посмотреть сообщение
вы путаете 2 логики, логику базы и бизнес логику
Давайте не будим теоретизировать, а говорить конкретно о том что есть в этом топике. Я прекрасно знаю все эти теории про бизнес логику и прочее, и как все они из красивой теории вырождаются в различные химеры когда сталкиваются с реальностью. Которая диктует другие приоритеты по типу похер на говнокод, но надо вчера, или похер на всё но надо что бы выполнялось за 0 секунд. И куча прочих других вариантов. Речь не об этом. Речь о конкретном обсуждаемом примере.

И да, ничего криминального не вижу в обсуждаемом примере. В приложении есть данные. Они абстрагированы в конкретном объекте в виде "таблиц" которые представляют собой наборы массивов. Взаимодействие с данными идут через интерфейсы этого объекта. Полноценная база данных не нужна. И сколько не придумывай красивых названий, бизнес логика и прочее - всё это в конечном счёте код.

Цитата Сообщение от Dr9vik Посмотреть сообщение
осталось понять зачем возвращать определенные столбцы если можно вернуть всю строк
Тут на меня наехали мол я в воображаемом примере object использовал, а вы предлагаете мне оверхед в виде кучи ненужного кода. А если таблица содержит массивы обектов, каждый который по мегабайту. А мне например нужен несчастный bool только. То вы тоже предлагаете возвращать строку с мегабайтами мусорных данных? И это не будет банальная ссылка - потому как нельзя отдавать ссылки на объекты в таблице - потому как можно сделать SELECT, получить ссылку и по ней уничтожить данные. Это будет полноценное копирование мегабайт мусорных данных.

Цитата Сообщение от Dr9vik Посмотреть сообщение
безграничное множество методов
Ну с помощью кортежей я сделал 1 метод для всего. Даже с Where - делегат выборки строки. И дабы не быть голословным приведу пример этого метода для вариантов:
Цитата Сообщение от dev_usr Посмотреть сообщение
Ну ещё для примера:
1 вариант - хочу получить строку 100, столбцы 1,4
C#
1
2
3
4
5
6
7
static bool where(in int col0)
{
     if (col0 == 100) return true;
     return false;
}
 
(long x1, byte[] x2) = DB.Select<long, byte[]>("MyTable", "col1", "col4").Where<int>(where, "col0");
Я тут даже через делегат передаю условия выборки. Тут я про условия даже не начинал обсуждения. Хотя это тоже нетривиальная задача была. Как передавать делегаты опять же переменным количеством значений.
0
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
11.07.2022, 16:50
сами придумали велосипед
сами думаете как его решить

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

правда всеравно придется написать 100 методов на фронте...
0
2 / 2 / 1
Регистрация: 12.06.2022
Сообщений: 44
11.07.2022, 17:32  [ТС]
Цитата Сообщение от Dr9vik Посмотреть сообщение
сами придумали велосипед
сами думаете как его решить
Ээээ... Это как бы и есть программирование. Есть задача. Её решает кто то. Можно заплатить другому или делать самому.

Цитата Сообщение от Dr9vik Посмотреть сообщение
есть дапер, где указываете на какую модель мапить и мапите
БД это не простой массив, что бы можно было пользоваться сахаром в виде Linq. Потому как массивы делятся на страницы, и есть механизм гибкого управления этими страницами при удалении или расширении таблицы, а не тупое удвоение массива как делает например List. Опять же есть индексы. Внешние ключи и прочее. Локировка таблиц и отдельных колонок, например есть локировка на чтение, а есть на изменение. При этом на чтение могут локировать много потоков, а на изменение только 1.

Опять же Linq обеспесивает достаточно примитивные варианты выборок, в то же время как в делегате можно заложить абсолютно любую логику. Например можно сделать дополнительные SELECT, получить массивы данных и организовать логику JOIN, да вообще что угодно.

Поэтому просто взять какой нибудь List или Dictionary и использовать Linq - этот вариант не подходит для для обсуждаемого кейса.
0
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
11.07.2022, 17:44
Цитата Сообщение от dev_usr Посмотреть сообщение
1 вариант - хочу получить строку z, столбцы x,y
1 методом решаю эту проблему
написав заранее 1-2 метода в базе, в который будет приходить массив полей и массив условий
дапером мапя на класс таблицы
Цитата Сообщение от dev_usr Посмотреть сообщение
БД это не простой массив, что бы можно было пользоваться сахаром в виде Linq. Потому как массивы делятся на страницы, и есть механизм гибкого управления этими страницами при удалении или расширении таблицы, а не тупое удвоение массива как делает например List. Опять же есть индексы. Внешние ключи и прочее. Локировка таблиц и отдельных колонок, например есть локировка на чтение, а есть на изменение. При этом на чтение могут локировать много потоков, а на изменение только 1.
Опять же Linq обеспесивает достаточно примитивные варианты выборок, в то же время как в делегате можно заложить абсолютно любую логику. Например можно сделать дополнительные SELECT, получить массивы данных и организовать логику JOIN, да вообще что угодно.
Поэтому просто взять какой нибудь List или Dictionary и использовать Linq - этот вариант не подходит для для обсуждаемого кейса.
много слов, причем тут LINQ?
0
2 / 2 / 1
Регистрация: 12.06.2022
Сообщений: 44
11.07.2022, 17:48  [ТС]
Но самое главное BD это не массив объектов класса. А массив массивов. Потому как если делать банальный SELECT в таблице без ключей. То это обычный перебор. Если это массив объектов - то этот перебор будет из двух операций - сначала получаем ссылку на объект, потом получаем ссылку на поле объекта.

Если это простой массив например int - то перебор такой последовательной памяти - это вообще одна инструкция процессора. Не удивлюсь что эта инструкция и ещё какое сравнение может делать за этот такт.
0
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
11.07.2022, 17:54
Цитата Сообщение от dev_usr Посмотреть сообщение
Потому как если делать банальный SELECT в таблице без ключей
вы хоть знаете для чего ключи надо?
нормально база без ключей может справиться
0
2 / 2 / 1
Регистрация: 12.06.2022
Сообщений: 44
11.07.2022, 17:58  [ТС]
Цитата Сообщение от Dr9vik Посмотреть сообщение
дапером мапя на класс таблицы
Цитата Сообщение от Dr9vik Посмотреть сообщение
много слов, причем тут LINQ?
Надоело реально. Любят тут навести загадочности, а собеседник должен из себя предсказамуса строить.

Если вы имеете ввиду что пользуетесь какинибудь Entity или ещё каким ORM (коих огромное количество), то пишите конкретно что именно. И по поводу ORM - все они не волшебным способом мапят объекты на таблицы. И часто внутри себя такого наделают, что потом долго удивляешься что простейший запрос выполняется чёрти знает сколько.

И тут нету спора преимущества или недостатка той или иной ORM. И использовать её или нет. Я чётко написал - модель работы подразумевается как работа с таблицами, а не объектами.

Добавлено через 1 минуту
Цитата Сообщение от Dr9vik Посмотреть сообщение
вы хоть знаете для чего ключи надо?
нормально база без ключей может справиться
Диалог закончен.

Я не знаю зачем мне ключи. И я не знаю зачем я делаю B-дерево. Я не знаю зачем я постоянно запускаю таймеры в программе что бы измерить сколько миллесекунд занимают тестовые запросы на простейших SELECT которые тупо перебирают, и играюсь с размерами массивов и другими параметрами что бы уменьшить время.
Флаг вам в руки в выборке в таблице на гигабайты и запросов этак 1000 в секунду.
0
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
11.07.2022, 18:10
Цитата Сообщение от dev_usr Посмотреть сообщение
Надоело реально. Любят тут навести загадочности, а собеседник должен из себя предсказамуса строить.
из всех постов я понял что вы не понимаете то на чем вы пишите
Цитата Сообщение от dev_usr Посмотреть сообщение
Я чётко написал - модель работы подразумевается как работа с таблицами, а не объектами.
чивоооо?
у вас есть таблица в базе, что бы ее представь коду надо замапить эту таблицу на классы
как вы это делать будете дело десятое
классы должны соответствовать таблицам
Цитата Сообщение от dev_usr Посмотреть сообщение
Диалог закончен.
индексы, а не ключи
потом про б деревья задвигают...хоспаде...
0
2 / 2 / 1
Регистрация: 12.06.2022
Сообщений: 44
11.07.2022, 18:27  [ТС]
Цитата Сообщение от Dr9vik Посмотреть сообщение
индексы, а не ключи
Ну ошибся, причитал одно, подумал об другом. Или вы думаете что я тут только и сижу что на форум пялюсь, я как бы ещё 10 дел делаю. Заклемите меня позором теперь.
А по поводу внешних ключей, я их использую на постоянке везде. Можно и не использовать - тогда сам ручками проверяй, а есть ли например клиент с номером 10. Вот только зачем это делать каждый раз вручную - если это можно заложить непосредственно в код БД.

Добавлено через 4 минуты
Цитата Сообщение от Dr9vik Посмотреть сообщение
чивоооо?
у вас есть таблица в базе, что бы ее представь коду надо замапить эту таблицу на классы
Это я должен писать чиво. Что бы получить данные с БД - достаточно просто их получить. И сложить например в локальные переменные. И так десятилетиями работали. И только с развитием программирования появились всякие ORM.

Цитата Сообщение от Dr9vik Посмотреть сообщение
классы должны соответствовать таблицам
Потому что это вы так сказали? А если не соответствуют - то всё, ничего работать не будет?

А как например работать программе написанной на С с базой данных? Она ведь ни о каких классах и в помине не знает.
0
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
11.07.2022, 18:34
Цитата Сообщение от dev_usr Посмотреть сообщение
Ну ошибся, причитал одно, подумал об другом. Или вы думаете что я тут только и сижу что на форум пялюсь, я как бы ещё 10 дел делаю. Заклемите меня позором теперь.
А по поводу внешних ключей, я их использую на постоянке везде. Можно и не использовать - тогда сам ручками проверяй, а есть ли например клиент с номером 10. Вот только зачем это делать каждый раз вручную - если это можно заложить непосредственно в код БД.
тогда объясните причем тут C# и ваша база?

Добавлено через 1 минуту
Цитата Сообщение от dev_usr Посмотреть сообщение
А как например работать программе написанной на С с базой данных? Она ведь ни о каких классах и в помине не знает.
вы ошиблись разделом форума
вам сюда https://www.cyberforum.ru/c/
0
2 / 2 / 1
Регистрация: 12.06.2022
Сообщений: 44
11.07.2022, 18:39  [ТС]
Цитата Сообщение от Dr9vik Посмотреть сообщение
тогда объясните причем тут C# и ваша база?
Т.е. вы опустились до уровня что запрещаете мне в C# как то писать не так как это видите вы?

Знаете почему я пишу эту переписку, я надеялся что я встречу кой то рабочий вариант. Мол вот этот код лучше, по тому то и потому. Нихрена я не встретил. Как всегда. Только завуалированные абстракции - за которыми так удобно прятать свою не компетенцию, или банально лень. Всё скатилось в типичный срач.

P.S. отдаю вам последнее слово.
0
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
11.07.2022, 19:05
Цитата Сообщение от dev_usr Посмотреть сообщение
Знаете почему я пишу эту переписку, я надеялся что я встречу кой то рабочий вариант. Мол вот этот код лучше, по тому то и потому. Нихрена я не встретил. Как всегда. Только завуалированные абстракции - за которыми так удобно прятать свою не компетенцию, или банально лень. Всё скатилось в типичный срач.
я вам предложил вариант рабочий, но вас он не устроил...ибо слооожна

C#
1
2
3
4
public async Task<Table> Get(IList<string> fields, Dictionary<string, string> where)
{
    return  await mapper.Sql<Table>($"Select * From get({json.SerializeObject(fields)}, {json.SerializeObject(where)})");
}
в базе создаете метод "get" и делаете все что хотите с теми данными что пришли, главное вы выходе совпадали названия полей со свойствами в классе
все решение...
впрочем какая у вас база мне не известно, на прогрессе это делается все быстро
1
2 / 2 / 1
Регистрация: 12.06.2022
Сообщений: 44
12.07.2022, 23:17  [ТС]
Усовершенствовал. Выкинул в Where передачу имён колонок. Теперь имена берутся из параметров делегата. Теперь выглядит так:

C#
1
2
3
4
5
6
7
static bool where(in int col0)
{
     if (col0 == 100) return true;
     return false;
}
 
(long x1, byte[] x2) = DB.Select<long, byte[]>("MyTable", "col1", "col4").Where<int>(where);
Добился этого следующим кодом:
C#
1
2
MethodInfo inf = where.GetMethodInfo();
ParameterInfo[] pars = inf.GetParameters();
Измерял сколько времени занимает эта рефлексия: на средней машине приблизительно 30 микросекунд. Неплохо. В дальнейшем планирую кешировать результат.

Были эксперименты что бы сделать так:

C#
1
(long x1, byte[] x2) = DB.Select<long, byte[]>("MyTable", "col1", "col4").Where(where);
Т.е. удалить передачу типов. В принципе рабочий вариант получился с использованием:
C#
1
Delegate.DynamicInvoke
На таблице в 1000000 строк без индекса - запрос выполнялся ~400ms. Специально подбирался что бы правильная строка была в конце. Запрос с передачей типов выполняется 8ms. Т.е. динамическое проверка типов делегата съела всю производительность. Поэтому этот вариант отбрасывается. Таже проблема была с dynamic типами.

Удалить передачу типов в Select - тоже никак не получается. Потому как если не передавать типы, при помощи которых можно произвести деконструкцию, то надо будет городить out параметры. Что по размером и простоте выглядит хуже.

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

И да глянул что мне тут токсичный товарищ предложил. Наконец не пустые слова, а код. Посмотрел я на это, мда. А пыжился то как. Тут куда не посмотри сплошной оверхед. Я уже не говорю про json сериализацию, это какой то абсурд в высоко нагруженном приложении. Хрен с ней. Пусть будут имена таблиц. Но как минимум надо эту строку распарсить. Выделить какие параметры на вход, на выход. Короче куча кода и времени. При таком подходе лишаемся возможности найти ошибки типов на стадии компиляции.
Опять же возвращение целого класса, вместо конкретных параметров. А если нужно сделать 1000000 селектов в секунду, сколько мусорных данных придётся резервировать в куче. Что бы сборщик потом захлёбывался. А сам маппер. Ему что бы сопоставить со свойствами класса - придётся использовать рефлексию, которая убъёт всю производительность. Неудивительно что современные проги написанные таким бездумным подходом требуют гигабайты и гигагерцы.

Короче - кроме как вопрос про кортежи я и не собирался обсуждать. Так что всякие любители подоказывать не относящиеся к этой теме вопросы могут сразу валить в другие темы.
0
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
12.07.2022, 23:55
я очень рад за вас
видите, сами справились
0
2 / 2 / 1
Регистрация: 12.06.2022
Сообщений: 44
13.07.2022, 16:43  [ТС]
Нашёл способ получить уникальный идентификатор делегата:

C#
1
where.Method.MetadataToken
Таблицу, параметры, а также имена параметров в where ищу 1 раз и кладу в модельку которую помещаю в кеш. При следующих вызовах время трачу только на поиск в кеше.

Ещё удалось увеличить скорость работы. При этом SELECT остался такой же лаконичный.

Добавлено через 42 минуты
Хотя поспешил. Выходные параметры могут быть разными, а where может быть 1. Всё это решается конечно если всё запихнуть в 1 функцию - но тогда красивый select превращается в... некрасивый короче. Буду думать дальше.
0
2 / 2 / 1
Регистрация: 12.06.2022
Сообщений: 44
14.07.2022, 02:26  [ТС]
Сделал жёсткую привязку таблицы и выходных параметров к делегату через атрибуты.
C#
1
2
3
4
5
6
7
8
[Out("Table", "col0", "col1")]
static bool where(in long x1, in int x2)
{
       if (col0== 998000 && col1== 1) return true;
       return false;
}
//~~~
(long col2, int col3) = DB.Select<long, int>().Where<long, int>(where);
Проверил, влияют ли атрибуты на скорость делегата. Нет. Время одинаковое со старым вариантом.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.07.2022, 02:26

Преобразование типов - большая нагрузка на ЦП
Здравствуйте. Пишу downloader, так сказать, менеджер закачки. Вычисляю while ((int)(readCount = DownloadStream.Read(buffer, 0,...

Взаимное преобразование численных типов данных
Объясните новичку на C#. Задание. Создать консольную программу взаимных преобразований численных типов данных в соответствии с вариантом. В...

Преобразование типов: что лучше использовать
Что лучше использовать для конвертирования одного типа в другой? Использовать TryParse и Parse в структурах (int, uint, ulong и т.д) или же...

Возможно ли создать своё преобразование типов
Есть какая-то структура: struct MyStruct { public int value; public string SomethingElse; } Можно ли сделать,...

Не могу вызвать неявное преобразование типов в Main для проверки "Перегрузки операторов преобразования типов"
Добрый день, Написал явное преобразования типов из дроби в тип double (явное потому что если делаю неявным то оно конфликтует с...


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

Или воспользуйтесь поиском по форуму:
36
Ответ Создать тему
Новые блоги и статьи
Был праздник вчера, а я и не знал.
kumehtar 28.07.2026
27. 07. 2026г. Intel Core 2 Duo исполнилось 20 лет Новости компьютерного мира и их обсуждение (4) Салют, шампанское, овации! :drink:
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр. Дословно, отклонённая. . .
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
Очистка реквизитов и табличных частей документа при копировании (вариант 2)
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2. Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru