Автоматическое обнаружение компилятором добавления одного и того же экземпляра объекта в контейнер в цикле

StackOverflow https://stackoverflow.com/questions/1465486

Вопрос

Это глупая ошибка:

List<Foo> fooList = new List<Foo>();
Foo f = new Foo();
while (something.Read()) {
    f.Fill(something.GetRecord());
    fooList.Add(f);
}

Конечно, я должен создать экземпляр нового Foo внутри цикла.

Может ли компилятор обнаружить такого рода ошибку во время компиляции?

На наивный взгляд кажется, что он должен быть способен обнаружить это поведение (заполнение списка экземплярами одного и того же объекта в цикле).Затем он должен выдать предупреждение типа "Вы заполняете контейнер одним и тем же экземпляром более одного раза"..

Итак, насколько же я наивен?Знаете ли вы какой-нибудь язык, где существует что-то подобное?

Это было полезно?

Решение

Да, это возможно.

Однако я не думаю, что инструмент или компилятор сами предупредили бы об этом, поэтому вам придется использовать инструмент, который может быть расширен вашими собственными анализами.Для Java, Найди жуков является таким инструментом.Для C, C ++ и т. Д, gcc 4.5 позволит подключать плагины чтобы люди могли писать свои собственные расширения, и лязг from LLVM тоже предназначен для этого.Существует также Дегидратация из Mozilla, опять же для C ++.Для языков MS существует Фреймворк Phoenix.

Итак, вопрос в том, как вы пишете этот анализ?Это немного сложнее и зависит от инструмента.Но в основном:

  • вы можете довольно легко обнаружить циклы (поищите "Сильно связанные компоненты").,
  • анализ псевдонимов может сказать вам, относится ли конкретная переменная или параметр только к одному объекту или ко многим объектам (возможно, ищите "абстрактные объекты").,
  • вы можете найти нужный контейнер, используя статический тип объекта или переменной.

Таким образом, вы могли бы довольно легко обнаружить вызов List<>.append(x) в цикле, где x может ссылаться только на один объект.

Другие советы

Что делать, если вы хотите заполнить список<> с несколькими экземплярами объекта?Нужно ли вам украсить свой код с помощью #pragma значит, компилятор оставляет вас в покое?

Как бы вы вообще объявили класс с такого рода ограничениями?Список<> на самом деле это не что иное, как класс C #, вы можете декомпилировать mscorlib.dll и увидеть его полную реализацию.Таким образом, чтобы обладать такого рода знаниями, они должны были бы быть где-то жестко запрограммированы.Атрибуты?Это было бы невероятно ограничивающим фактором.Специальные методы проверки вашего кода?Это добавило бы накладных расходов вашим объектам.

Такого рода вещи никогда (и я действительно имею в виду никогда) не используются по какой-либо причине:чрезвычайно небольшое количество случаев, когда это помогло бы, а не помешало, даже близко не перевешивает вполне реальные затраты, которые потребовались бы как из-за сложности реализации (самого фреймворка И вашего кода), так и из-за снижения производительности (из-за перегруженных объектов, которые приходится перемещать по памяти, когда GC делает свое дело).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top