У меня есть общедоступное свойство, установленное в моей форме типа ListE<T>, где:
public class ListE<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
Да, это непросто, но именно этого требует Дизайнер, чтобы он отображался как редактируемая коллекция в окне «Свойства». Что он делает! Итак, я нажимаю маленькую кнопку [..], чтобы редактировать коллекцию, а затем нажимаю Добавить, чтобы добавить элемент в коллекцию.
Arithmetic operation resulted in an overflow.
Это очень простой список, немного больше, чем расширяющийся массив. Единственная часть, которая во всем этом приближается к арифметике, - это функция расширения, и даже в ней используется сдвиг влево, а не умножение, чтобы не переполняться. Все это заставляет меня думать, что это исключение возникает внутри конструктора, возможно, из-за моего небольшого невнимания к деталям реализации с моей стороны, но я не могу найти способ проверить или отладить этот сценарий. Есть ли у кого-нибудь умные идеи?
Обновлено: Да, я могу успешно использовать свойство, ну даже вручную, т.е. в обработчике OnLoad, и я полагаю, что мне придется прибегнуть к этому, если я не смогу заставить это работать, но это было бы не идеально. :(
Ненавижу сообщать вам об этом, но List <T> из стандартной библиотеки имеет точно такую же подпись. Если вы наберете «List <T>» и нажмете F12 в VS, вы перейдете к восстановленному определению.
Фактически, IList <T> сам реализует другие общие интерфейсы вместе с IEnumerable, поэтому я мог бы сократить это как просто ListE <T>: IList <T>, IList, но этот способ более явный.





Можно начать с того, что он может выполнять вычисления с вашим свойством ListE`1 :: Count. Если это имеет какой-то тонкий недостаток (т.е. это сложнее, чем вернуть this.innerList.Count), это может привести к арифметическому переполнению дизайнера при выполнении какой-либо операции. Обычно арифметические переполнения не происходят, если специально не запрашивается использование
checked
{
// ...
}
синтаксис.
Свойство My Count простое: public int Count {get {return _maxIndex + 1; }} где _maxIndex - последний элемент в массиве.
У меня также определенно нет проверенного кода {}, так что это только доказывает, что это происходит где-то в конструкторе, не так ли?
@monoxide: это может быть ваш _maxIndex + 1, или то, как они ИСПОЛЬЗУЮТ ваш _maxIndex + 1 (скажем, Int32.MaxValue) переполнены. Самое главное, я не совсем уверен, как вы это отлаживаете.
Джо решил, как отладить его, а то, что было переполнено, было _list.GetUpperBound (0) * 2 в моем методе расширения. Каким-то образом дизайнер устанавливал (защищенный) список в массив нулевой длины. Лучшее предположение, он пытался оценить ((uint) -1) * 2.
Я не могу понять, что побуждает вас попытаться таким образом заново изобрести колесо List <T>, но чтобы ответить на ваш вопрос: я бы добавил строку «System.Diagnostics.Debugger.Break ()» в конструктор вашего класса. .
Затем попробуйте использовать его в дизайнере, и вы увидите всплывающее окно с вопросом, хотите ли вы подключить отладчик. Подключите второй экземпляр Visual Studio в качестве отладчика, и вы сможете установить некоторые точки останова в своем коде и начать отладку.
Повторная установка колес может быть забавным. Также нет полиморфно правильного способа расширения любой из базовых коллекций для включения событий, потому что ни одна из определенных функций не является переопределяемой, поэтому, если я верну ее обратно в исходный класс, я снова не получу событий.
И для записи, среди прочего, по какой-то причине он пытался использовать CopyTo (), а я не реализовал его. Сначала исправьте это, а затем посмотрите, куда мы пойдем дальше ...
Вам не нужно добавлять Debugger.Break (); вызовите свой код, чтобы отладить его. Вы можете просто открыть другой экземпляр VS и присоединиться к тому, в котором вы его используете, и вы сможете без проблем отлаживать его (просто убедитесь, что у вас загружены символы).
Это не связано с вашей проблемой, но имейте в виду, что вы можете указать только то, что ListE <T> реализует IList <T>.