Используете уникальные идентификаторы для объектов?
Работал с самописной коллекцией объектов, у каждого из которых была модель и представление. Байндингов нет, т.к. не охота заморачиваться их реализацией в самописных контролах. При операциях добавления-удаления представлений стали почему-то выкидываться исключения, что представления для удаления не найдены, хотя мне казалось, что они точно были в коллекции - ведь данные отображаются те же. При удалении представлений я сравниваю их по ссылке. Смотрю под дебагом - модели у представлений одинаковые, данные в них одинаковые, почему считает, что это разные представления и ссылки на них не равны? Оказалось, что при определённых условиях коллекция создаёт новые представления с теми же моделями, потому и данные отображаются одинаковые. Но пока не добавил уникальные идентификаторы для представлений, не смог понять это.
Если бы сравнивал представления не по ссылке, а скажем по значениям моделей (в моделях есть свои уникальные идентификаторы), то всё бы работало, баг бы не проявлялся. Только память бы постепенно утекала.
Сама ссылка на объект и есть вполне себе уникальный айди.
смотря что под этим понимать. Вначале должно быть определение, какие два объекта будут считаться одинаковыми.
Вот сделал я клон моего объекта - это одинаковые объекты или разные?
А вы любой класс начинаете с добавления ему какого-то уникального идентификатора?
Если класс "сидит" в базе, то скорее всего да. Но всегда есть исключения
Вначале должно быть определение, какие два объекта будут считаться одинаковыми.
Вот сделал я клон моего объекта - это одинаковые объекты или разные?
Две ссылки на один и тот же объект - это одинаковый объект. Тут-то разногласий не будет? Железное определение.
if (myIsland == yourIsland) throw new Exception();
А вы любой класс начинаете с добавления ему какого-то уникального идентификатора?Если класс "сидит" в базе, то скорее всего да. Но всегда есть исключения
Вы слишком далеко копаете, в базы какие-то лезете. Всё проще. У меня во вьюшном списке сидели представления, и по-ошибке могли создаться несколько вьюх на одну и ту же модель в одном и том же списке. А не должны были. Там при одной операции одна вьюха удалялась, а другая создавалась, так что внешне казалось, что нужный объект всё ещё в списке. А внутри списка я храню ссылку на удалённую из списка вьюху. Выбираю оставшуюся вьюху, которая видна в списке, сравниваю с сохранённой, и должен удалить, если они равны - а они не равны.
Я пишу свой контрол для коллекций представлений. Среди прочего он должен запоминать выбранный объект. А также пытаюсь реализовать операцию обмена объектами между разными коллекциями. Я сделал для своей коллекции пока добавление и удаление как "атомарные" операции - т.е. происходят полностью внутри коллекции. А вот обмен, это когда из другой коллекции тащат предмет в мою коллекцию. Тогда моя коллекция должна отдать свой предмет и принять чужой. Если делать это как две последовательные атомарные операции - сначала удалить свой объект, потом принять чужой, то вот ошибка такая возникла. А реализовать обмен как отдельную атомарную операцию пока не придумал как. Да и не охота - придумал workaround через две простых, найдя описанную в начале ошибку и исправив.
В одном списке количества объектов все равно меньше, чем в реальности. А теперь представьте комбинацию объектов и их трансформацию какое решение из этого вышло? Причем по некоторым объектам повторений то есть копий клонов ещё больше. Какое решение из этого вышло?
Второй вопрос по оптимизации приложений, почему вообще тут в Германии все работает с ошибками? В России и других странах бывшего постсовета у меня все чисто, а здесь полный бардак.
Сама ссылка на объект и есть вполне себе уникальный айди.
------
С чего бы это? особенно с учетом возможной автоматической выгрузки/загрузки объектов...
Найдите второй объект с такой же ссылкой. А вот всякие айдишники могут дублироваться - я же могу несколько объектов представлений иметь, которые будут содержать одну и ту же модель, а значит и айдишник, который она из базы данных или ещё откуда берёт.
Выгрузка загрузка - что вы имеете ввиду? Даже если адрес объекта обновится, то ссылка на него обновится у всех.
Для этой задачи мне нужно не сравнение по логике, а сравнение по физическому присутствию, если можно так выразиться. Для моделей пойдёт сравнение по логике (чтобы айдишники были одинаковые).
Но вообще я другое имел ввиду под айдишниками для объектов. Я имел ввиду что-то типа
MyClass
{
static ulong idCounter = 0;
ulong id;
public MyClass() { id = idCounter++; }
}
Когда я увидел под дебагом, что представления не равны, хотя подлежащие модели равны, то не поверил. Решил проверить, добавив такие айдишники, чтобы лишний раз убедиться, что это действительно разные представления с разными айди.
Да это вообще старый приём с приписанными айдишниками к каждому объекту. Не понимаю, что все удивляются и цокают языками. )))
В одном списке количества объектов все равно меньше, чем в реальности. А теперь представьте комбинацию объектов и их трансформацию какое решение из этого вышло? Причем по некоторым объектам повторений то есть копий клонов ещё больше. Какое решение из этого вышло?
Второй вопрос по оптимизации приложений, почему вообще тут в Германии все работает с ошибками? В России и других странах бывшего постсовета у меня все чисто, а здесь полный бардак.
Вы дескредитируете ИИ. С таким низкокачественным ИИ технологическая сингулярность никогда не наступит, и кожаные мешки всегда будут говнокодить и понукать вами, непризнанными железными гениями.
Железное определение.
Абсолютно
https://onecompiler.com/csharp/42wws4jdp
Вы слишком далеко копаете
Вопрос - Используете уникальные идентификаторы для объектов
https://onecompiler.com/csharp/42wws4jdp
У вас как раз моя ситуация - модель одна и та же (у вас просто данные скопированы), а инстансы представлений разные.
Если айди по смыслу должен иметь уникальный номер на инстанс, то не должно быть конструктора, копирующего этот айди. Каждый раз он должен присваиваться новый. У меня кстати счётчик айди простого типа (ulong) и статический, что по его природе уже гарантируют атомарность приращения и потокобезопасность. А значит и уникальность айди, если его задавать так
id = idCounter++;
Если айди по смыслу должен иметь уникальный номер на инстанс,
Не по смыслу, а так вам надо
Ну например так
Console.WriteLine($"Instance1 ID: 0x{RuntimeHelpers.GetHashCode(instance1):X8}");
Console.WriteLine($"Instance1 ID: 0x{RuntimeHelpers.GetHashCode(instance2):X8}");
Вариантов еще море
internal class Program { private static ulong idCounter = 0; static void Main(string[] args) { Task[] tasks = new Task[10]; for (int j = 0; j < tasks.Length; j++) { tasks[j] = Task.Factory.StartNew(Increment); } Task.WaitAll(tasks); Debug.WriteLine($"Counter: {idCounter}"); } private static void Increment() { for (int i = 0; i < 10000; i++) { idCounter++; } } }
internal class Program { private static ulong idCounter = 0; static void Main(string[] args) { Task[] tasks = new Task[10]; for (int j = 0; j < tasks.Length; j++) { tasks[j] = Task.Factory.StartNew(Increment); } Task.WaitAll(tasks); Debug.WriteLine($"Counter: {idCounter}"); } private static void Increment() { for (int i = 0; i < 10000; i++) { idCounter++; } } }
Да... Да, это не атомарно. Обманули! Пишут будто одну операцию, а сами сокращают i = i + 1.
В этом долбаном Сишарпе даже чтение и присвоение могут не быть атомарными. Короче, всё потенциально многопоточное надо заворачивать в запирания.
Зачем тогда какие то придурки сделали "Interlocked.Increment(ref сount);"?
А по моей ссылке чел пишет, что лучше использовать локи, и только если они слишком медленные, то ваш метод Interlocked.Increment. Но этот метод не гарантирует 100% потокобезопасность.
Interlocked.IncrementВ твоем конкретном примере применение Interlocked.Increment - это самый быстрый и 100%-о потокобезопасный вариант.
в моём конкретном случае поиска моей конкретной проблемы подошёл и мой первый способ
про потокобезопасность это я уже потом добавил )))
Переопредели GetHashCode.
А вообще, сравнивать объекты по ссылке - очень странное решение, не понимаю, как такое вообще пропустили через ревью. Никогда не сравнивнивай объекты через "==", вместо этого используй Equals :)
А вообще, сравнивать объекты по ссылке - очень странное решение, не понимаю, как такое вообще пропустили через ревью. Никогда не сравнивнивай объекты через "==", вместо этого используй Equals :)
Что за бред? Это где-то написано в доках? Если я сравниваю два объекта, то они же по ссылке сравниваются - т.е. сравнивается, равны ли их ссылки? А Equals и переопределить могут - получу неожиданный результат.
Мне тогда нужно было именно ссылки сравнить... Хотя, оператор == тоже могут переопределить.
Это всё фигня. Вот у меня сейчас другой вопрос всплыл. Можно сказать философский. Как яйцу опередить курицу? Как сделать так, чтобы при двойном клике не вызывался обработчик одинарного?
Можно щёлкать мышкой (или тапать пальцем) по контролу. При этом есть одинарный клик (последовательность действий: мышь нажали, мышь отпустили), и есть двойной. Клик проходит, когда мышь отпустили на том же объекте, на котором нажали. Вобщем всё стандартно... Пока придумал лишь задерживать обработчик одного клика - если за интервал между кликами, в течении которого клик считается двойным, не пришёл второй клик, то выполняю обработчик одинарного клика. Если этот интервал достаточно маленький, то пользователь может и не заметить. Хотя всё же будет ощущение подтормаживающего интерфейса.
Кроме как по времени никак не разделить
Вот что предлагает (не будем показывать пальцем кто). В .md формате
To handle a double-click event separately from a single-click event in Blazor, you can use JavaScript interop to control the timing and differentiate between single and double-clicks. Here's a clean approach using JavaScript to delay the single-click action slightly. If a double-click is detected within a short time, the single-click action will be ignored. 1. **JavaScript Helper**: Add a JavaScript function to detect single vs. double clicks. This function uses `setTimeout` to delay the single-click action, which is canceled if a double-click occurs within the delay period. ```html <script> window.clickHandler = { singleClickTimeout: null, handleClick: function(elementId, singleClickCallback, doubleClickCallback) { clearTimeout(this.singleClickTimeout); // Set up a timeout for single-click this.singleClickTimeout = setTimeout(() => { singleClickCallback(); }, 250); // Delay to allow for double-click detection // Detect double-click document.getElementById(elementId).ondblclick = () => { clearTimeout(this.singleClickTimeout); doubleClickCallback(); }; } }; </script> ``` 2. **Blazor Component**: Set up your component with `@ref` to access the element ID in JavaScript and call the JavaScript function to handle clicks. ```razor @page "/click-sample" <button @ref="clickButton" @onclick="HandleSingleClick">Click me</button> @code { private ElementReference clickButton; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await JS.InvokeVoidAsync("clickHandler.handleClick", clickButton.Id, DotNetObjectReference.Create(this), nameof(SingleClickAction), nameof(DoubleClickAction) ); } } [JSInvokable] public void SingleClickAction() { // Logic for single-click action } [JSInvokable] public void DoubleClickAction() { // Logic for double-click action } private async Task HandleSingleClick(MouseEventArgs e) { // Prevent Blazor's default click behavior, handling it in JavaScript instead } } ``` 3. **Explanation**: - `clickHandler.handleClick` is a JavaScript function that handles click events for the button. - `SingleClickAction` and `DoubleClickAction` are Blazor methods decorated with `[JSInvokable]`, making them callable from JavaScript. - `HandleSingleClick` is the Blazor click handler, but it's empty here because JavaScript fully handles click detection. This approach will prevent the single-click handler from triggering when a double-click is detected, keeping the two actions distinct. You can adjust the delay for detecting double-clicks by modifying the timeout value in `setTimeout`.
Ну так я и сказал, что задержка обработчика одинарного клика пока единственное решение.
По-моему, логически тут ничего не сделать.
Нужно обходить. Пока решил, что заменю двойной клик на удержание нажатия.
У меня двойные клики раз в 10-20 реже одинарных должны быть, так что удержание не должно сильно раздражать пользователя.
Жаль, что ИИ не научили переносить строки вовремя )))
Что за бред? Это где-то написано в доках? Если я сравниваю два объекта, то они же по ссылке сравниваются - т.е. сравнивается, равны ли их ссылки? А Equals и переопределить могут - получу неожиданный результат.
Вопрос в том, что именно ты хочешь узнать сравнением.
Если твоя цель узнать указывают ли две ссылки на один и тотже объект, то, конечно, сравнивать нужно сслыки.
Если же тебе нужно сравнивать "состояния" двух объектов, то сравнивать нужно исключительно через Equals.
В твоем примере (и в 95-98% реального использования) сравнивать нужно именно состояние. А значит и сравнивать нужно через Equals.
Мне тогда нужно было именно ссылки сравнить...
Очевидно, что нет :) Во всяком случае, твоя коллекция ничего не знает о том, что объекты нельзя пересоздавать :)
В твоем примере (и в 95-98% реального использования) сравнивать нужно именно состояние. А значит и сравнивать нужно через Equals.
Мне тогда нужно было именно ссылки сравнить...Очевидно, что нет :) Во всяком случае, твоя коллекция ничего не знает о том, что объекты нельзя пересоздавать :)
Когда делаешь модели и представления, то в основе разных представлений может быть одна модель. Тогда сравнение по значениям полей покажет равенство. А мне нужно было понять, что это именно разные представления, хоть и с одинаковыми моделями.
Коллекция действительно не заботится, чтобы представления имели в основе лишь уникальные модели. Это не её задача. Тем более, что иногда надо позволять иметь дубли. Поэтому и потребовалось различать представления с одинаковыми моделями. Тут сравнение по ссылке вполне подойдёт - уникальные идентификаторы городить не надо. Я их приписал представлениям для тестовых целей, чтобы перепроверить.
Here's a clean approach
Оптимистично. Особенно про "clean".
This approach will prevent the single-click handler from triggering when...
Впринципе, "when" можно заменить на "at all".
Этот говнокод, конечно, работать не будет, но с синтаксисом он неплохо справился.
Кстати, когда делаешь на одном и том же элементе обработчики на одно нажатие и на удержание, то тоже немало попотеть приходится, если не знать, как. Обычно события удержания нету, и надо его самому эмулировать. При этом надо сделать, чтобы оно не помешало событию нажатия. Тут надо тогда заменить одно нажатие на клик - т.е. нажатие и отжатие на одном и том же элементе. А ужержание, если такого обработчика нет изначально, эмулируется подпиской сразу на три события: нажатия, отжатия и покидания элемента (если такое событие в вашем фреймворке есть). Далее после нажатия притормаживаем поток параллельно выполняемой таской (Task.Delay или что там у вас для этого), в которую передаём токен отмены. Если таска задержки закончилась, то выполняем код для логики удержания нажатия контрола. В обработчиках же отжатия и покидания элемента отменяем таску задержки - логично, т.к. если слишком рано отжали или при нажатии сдвинули указатель или палец за пределы контрола, то удержания не произошло.
Проверил на своём проекте - отлично работает. Если зажал контрол, то события клика не происходит, а происходит событие удержания. А если быстро нажал и отжал - то удержания нет, а есть просто клик.
Использую это удержание для вызова подсказки по элементу там, где нельзя задержать указатель поверх элемента - для тачевых интерфейсов например.
Тогда сравнение по значениям полей покажет равенство. А мне нужно было понять, что это именно разные представления, хоть и с одинаковыми моделями.
В сухом остатке мы имеем твою ошибку :) В любом случае.
Т.е. либо ты выбрал неправильный контейнер. Либо ты неправильно сравниваешь :)
Вопрос в том, чему ты на этой ошибке научишься. Если запендюришь какой-то левый id, то значит ничему ты на этой ошибке не научился :) Вот собственно и все
Так я и создал тему, когда у меня такая ошибка вылезла. Когда всё хорошо, я чилю на сёрфинге и сюда не захожу. )))
Чему тут учиться? Я уже через время всё забуду, что тут говорили. Когда снова возникнет такая проблема, я скорее всего снова буду искать, как лучше различать объекты. Для быстрого теста такой проблемы как у меня "какой-то левый впендюренный айди" вполне подходит. Для более сложной ситуации наверное нет.
Этот говнокод, конечно, работать не будет
То есть вы тоже считаете, что должен выдаваться сразу 100% рабочий результат?
Сделать код рабочим, еще одно предложение написать
Но идея то останется всё та же: JS, timer и две функции.
Если у вас другая идея, можно также попросить изменить.
И для проверки идеи очень неплохо. Не нравится - проси другую.
При 15-20 млн сгенерированных строк - хорошо если получится поделить на блоки...О чём-то речь мы ведем? Какие миллионы?
Согласен - проблема раздута. Уже выяснили, что ИИ копирует чужой уже написанный код и пытается по методу калейдоскопа смиксовать из него что-то удобоваримое. Маленькие скрипты и небольшие группы классов по известным темам, которые написаны во многих тысячах вариантов, у ИИ зоходят неплохо. Проектов на миллионы строк было куда меньше для обучения, если вообще были. Поэтому ничего подобного таким проектам ИИ выдавать не сможет. А в скорости и вообще придут к выводу, что это просто ещё одна поисковая и справочная система. При этом могущая в любой момент выдать ложный результат. Поэтому проверке должно подвергаться, по-хорошему, всё, что она выдаёт.