Как спроектировать мой C # jQuery API таким образом, чтобы его не было сложно использовать?

Я делаю клон jquery для C #. Прямо сейчас я Мы настроили его так, чтобы каждый метод был методом расширения на IEnumerable , поэтому он хорошо работает с существующими проектами, которые уже используют HtmlAgilityPack . Я думал, что смогу обойтись без сохранения состояния ... однако затем я заметил, что jQuery имеет два метода .andSelf и .end , которые «выталкивают» самые недавно сопоставленные элементы из внутреннего стек. Я могу имитировать эту функциональность, если изменю свой класс так, чтобы он всегда работал с объектами SharpQuery, а не с перечисляемыми, но проблема все еще существует.

В JavaScript вам автоматически предоставляется документ Html, но при работе с C # у вас есть чтобы явно загрузить его, и вы можете использовать более одного документа, если хотите. Похоже, что когда вы звоните $ ('xxx' ) по сути вы создаете новый объект jQuery и начинаете заново с пустым стеком. В C # вы не захотите этого делать, потому что вы не хотите перезагружать / повторно загружать документ из Интернета. Поэтому вместо этого вы загружаете его один раз либо в объект SharpQuery, либо в список HtmlNodes (для начала вам нужен только DocumentNode).

В документации jQuery приводится этот пример

$('ul.first').find('.foo')
  .css('background-color', 'red')
.end().find('.bar')
  .css('background-color', 'green')
.end();

У меня нет метод инициализатора, потому что я не могу перегрузить оператор () , поэтому вместо этого вы просто начинаете с sq.Find () , который работает с корнем документа, по существу выполняя то же самое. Но затем люди попытаются написать sq.Find () в одной строке, а затем sq.Find () где-нибудь в будущем, и (справедливо) ожидать, что он снова будет работать с корнем документа ... но если я поддерживаю состояние, значит, вы только что изменили контекст после первого вызова.

Итак ... как мне разработать мой API? Могу ли я добавить еще один метод Init , с которого должны начинаться все запросы, который сбрасывает стек (но тогда как мне заставить их начинать с этого?), Или добавить Reset () , который они должны звонить в конце своей линии? Могу ли я вместо этого перегрузить [] и посоветовать им начать с этого? Могу ли я сказать «забудьте об этом, никто все равно не использует эти функции с сохранением состояния?»

В принципе, как бы вы хотели, чтобы этот пример jQuery был написан на C #?

  1. sq ["ul.first"]. Find ( ".foo") ...
    Downfalls: Злоупотребление свойством [] .

  2. sq.Init ("ul.first"). Find (". foo") ...
    Downfall: Ничто на самом деле не заставляет программиста начинать с Init, если я не добавлю какой-нибудь странный «инициализированный» механизм; пользователь может попробовать начать с . Найти и не получить ожидаемого результата. Кроме того, Init и Find в любом случае практически идентичны, за исключением того, что первый также сбрасывает стек.

  3. sq.Find ("ul.first"). Find (". Foo ") ... .ClearStack ()
    Ошибки: программист может забыть очистить стек.

  4. Не могу этого сделать.
    end () не реализовано.

  5. Используйте два разных объекта .
    Возможно, используйте HtmlDocument в качестве основы, с которой должны начинаться все запросы, а затем каждый метод после этого возвращает объект SharpQuery , который можно связать. Таким образом, HtmlDocument всегда сохраняет исходное состояние, но объекты SharpQuery могут иметь разные состояния. К сожалению, это означает, что мне нужно реализовать кучу вещей дважды (один раз для HtmlDocument, один раз для объекта SharpQuery).

  6. new SharpQuery (sq) .Find ("ul.first"). Find (". Foo"). ..
    Конструктор копирует ссылку на документ, но сбрасывает стек.

5
задан mpen 4 November 2010 в 00:55
поделиться