Здравствуйте, IT, Вы писали:
R>>Нельзя, не скомпилируется
IT>Почему это? IsNullOrEmpty компилируется а Format нет. У меня это кругом в linq2db, заменил на Format всё отлично компилируется.
Будет ошибка, если первый параметр строка. Компилятор в этом случае предпочитает смотреть на string.Format(string, params object[])
Здравствуйте, AndrewVK, Вы писали:
AVK>Чего то ничего не придумывается. Есть идеи?
KrymNash.NET
ну а если серьезно, в принципе, это интересно, но боюсь у каждого свои привычки и свои велосипеды.
мне вот нравятся string extension strTill и strAfter, которые возвращают подстроку до указанного паттерна или после.
еще генерация нормально распреденных случайных чисел.
public static void xmlSerialize<T>(T obj, string fileName)
public static void xmlDeserialize<T>(string fileName, out T obj)
то же для binary.
сериализируемый в XML dictionary
static public T getAssemblyAttribute<T>() where T : Attribute
averageOrZero, которая нуль на пустой последовательности возвращает а не исключениями кидается
standard deviation
в юниксное и из юниксного времени (в 4.6 вроде штатное сделали?)
всякие время в EST и американские Bank Holidays полагаю только мне нужны?
.isWeekend для даты вполне полезен всем, проверка на субботу или воскресенье
Здравствуйте, DreamMaker, Вы писали:
DM>ну а если серьезно, в принципе, это интересно, но боюсь у каждого свои привычки и свои велосипеды.
Ничего страшного. Нормальный программист свои привычки меняет, особенно если особого рационала в них нет. А упертые все равно свои велосипеды будут изобретать для несложных вещей.
DM>мне вот нравятся string extension strTill и strAfter, которые возвращают подстроку до указанного паттерна или после.
Полезная вещь. Родной Substring поддерживает только два сценария нормально — произвольный кусок из середины и произвольный кусок с начала. Когда нужно с конца код превращается в кракозябу. А руки написал хелпер как обычно не доходят, ибо мелкий и проще забить.
DM>еще генерация нормально распреденных случайных чисел.
Нормально в матсмысле, т.е. по Гауссу, или просто равномерное с хорошим качеством?
DM> public static void xmlSerialize<T>(T obj, string fileName) DM> public static void xmlDeserialize<T>(string fileName, out T obj) DM>то же для binary.
А тут какой смысл?
DM>сериализируемый в XML dictionary
Сериализуемость в XML понятие растяжимое. XmlDataSerializer, к примеру, словари сериализует искаропки.
DM> static public T getAssemblyAttribute<T>() where T : Attribute
Это в роадмапе уже есть.
DM>averageOrZero, которая нуль на пустой последовательности возвращает а не исключениями кидается
Это вроде уже реализовано даже.
DM>всякие время в EST и американские Bank Holidays полагаю только мне нужны?
Время в EST несложно и так посчитать, а праздники в код хардкодить — сомнительная практика. Я понимаю что не РФ, где каждый год выпускаюьт указ, но все таки изменения могут быть.
DM>.isWeekend для даты вполне полезен всем, проверка на субботу или воскресенье
Викэнд зависит от культуры, так что корректная реализация такого дело очень нетривиальное. МС, к сожалению, не озаботилась добавлением соответствующего функционала в календари.
DM>ну это на вскидку.
Ну вскидывай дальше.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, IT, Вы писали:
IT>Если честно, то я почти никогда не объявляю форматную строку отдельно от string.Format. Поэтому выглядеть это будет так:
IT>
Для константного формата и 6 шарпа уже не надо так делать. Надо так:
return $"Hello, {wellKnownNames[0]}";
А вот если не константа ...
IT>Это проблема не только этого метода, а любого расширения. Я сам хотел поднять эту тему. Сейчас у нас все расширения находяться в основном пространстве имён, что автоматически добавляет их все.
У меня лично много опыта использования экстеншенов на весьма крупных проектах и большом количестве этих экстеншенов. И на практике оказалось, что никаких проблем нет даже когда все экстеншены находятся в пространстве имен прикладного кода. Тип аргумента обычно достаточно селективен, особенно если не навешивать расширения на object.
Да посмотреть даже на сам Fx. Enumerable цепляется к очень распространенному типу, содержит очень большое количество расширений к нему (в фреймворке, наверное, рекордно большое), находится в том же самом неймспейсе, что и все коллекции, т.е. гарантированно попадает в любой код. Получается worst сценарий. Таки и что? Да ничего, все вполне нормально и удобно.
С другой стороны, когда у нас все в одном пространстве имен, это добавляет discoverability, которая при разнесении расширений по куче неймспейсов падает стремительным домкратом до уровня обычных статических методов, за что их не попинал только ленивый любитель С++ и свободных функций. И вот это уже реальная, а не теоретическая проблема.
IT>Как минимум я бы перенёс все расширения куда-нибудь в CodeJam.Extensions.
И что это даст? Лишний юсинг в прикладном коде?
IT> И заодно перетасовал бы файлы в проекте. Соответсвие папок пространсвам имён тоже вроде пока никто не отменял.
Очень неудобно. Если у меня классов много — будут неструктурированные длинные списки, если класс только один — дурацкая ситуация папки с одним файлом. ИМХО ну его нафик, средств навигации даже голой студии вполне достаточно, чтобы не искать классы по структуре папок. Я уж не говорю про решарпер.
Пространства имен предназначены для одного — обеспечения отсутствия конфликта имен. Попытка привязать к ним какую то еще ответственность — отличный способ прострелить себе ногу.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
И по-поводу сборки в nuget-пакет есть вот какие соображения.
При наличии specific framework (WinForms/WPF, WCF, ASP.NET MVC, System.XML и т.п.)-ориентированного кода будут тянуться лишние зависимости, которые понятное дело не всем нужны.
Мы так пробовали и в итоге отказались от одного большого пакета с хелперами.
Сейчас пользуемся идеей, описанной в https://github.com/phatboyg/Internals.
Т.е. подключаем репозиторий как сабмодуль, в солюшене делаем собственную сборку MyCompany.MyProject.Internals,
накидываем туда нужные файлы через "Add as link", подключаем нужные либы. Так в каждый проект попадают только реально нужные хелперы.
Одно другого не отменяет, но, возможно, есть смысл упомянуть и о таком подходе где-нибудь в документации.
И что они должны делать?
RD>И по-поводу сборки в nuget-пакет есть вот какие соображения. RD>При наличии specific framework (WinForms/WPF, WCF, ASP.NET MVC, System.XML и т.п.)-ориентированного кода будут тянуться лишние зависимости, которые понятное дело не всем нужны.
С самого начала было сказано — на пакеты делить по зависимостям. Но на текущем этапе разработка ведется только для полностью универсального кода, зависящего только от ядра фреймворка. Никаких WPF и ASP.NET. Чем, правда, System.Xml не угодил я не понял.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK>И что они должны делать?
Откусывать от начала/конца строки заданную подстроку (если она там есть). Удобно при разборе строк использовать e.g.
var str = @"SOMEDOMAIN\UserName@somedomain.com";
var userName = str.CutStart(@"SOMEDOMAIN\").CutEnd("@somedomain.com");
// Вместо if (str.StartsWith(@"SOMEDOMAIN\")) str = str.Substring(@"SOMEDOMAIN\".Length);
if (str.EndsWith("@somedomain.com") str = str.Substring(0, str.Length-"@somedomain.com".Length);
// P.S. str.Replace(@"SOMEDOMAIN\", "").Replace("@somedomain.com", "") в общем случае не подойдет, т.к. заменит по всей строке
AVK> Чем, правда, System.Xml не угодил я не понял.
К слову пришлось. Я решарперовским "Remove unused library references" часто пользуюсь — не люблю, чтобы в солюшене были ссылки на неиспользуемые либы.
Здравствуйте, RushDevion, Вы писали:
AVK>>И что они должны делать? RD>Откусывать от начала/конца строки заданную подстроку (если она там есть). Удобно при разборе строк использовать e.g.
Так а при откусывании зачем префикс/суффикс? Типа сперва нужно проверить на совпадение или это такой извращенный способ передать длину откусываемого?
AVK>> Чем, правда, System.Xml не угодил я не понял. RD>К слову пришлось. Я решарперовским "Remove unused library references" часто пользуюсь — не люблю, чтобы в солюшене были ссылки на неиспользуемые либы.
Не особо осмысленное занятие. Неиспользуемые сборки все равно не грузятся, даже если на них ссылка есть.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK>Так а при откусывании зачем префикс/суффикс? Типа сперва нужно проверить на совпадение или это такой извращенный способ передать длину откусываемого?
Да, проверить на совпадение, если совпало-откусить.
Наверное, название не очень удачное (просто я к нему привык, глаз замылился).
Это скорее аналоги TrimStart() и TrimEnd(), которые тримают подстроки, а не отдельные символы.
Хотя, с другой стороны "ababc".CutStart("ab") вернет "abc", а "ababc".TrimStart("ab") по идее должен вернуть только "c".
Здравствуйте, AndrewVK, Вы писали:
AVK>Для константного формата и 6 шарпа уже не надо так делать. Надо так:
Это когда ещё будет. Если помнишь, народ тут просил поддержку 4-го FW, а ты про 6-й решарпер.
IT>>Это проблема не только этого метода, а любого расширения. Я сам хотел поднять эту тему. Сейчас у нас все расширения находяться в основном пространстве имён, что автоматически добавляет их все.
AVK>У меня лично много опыта использования экстеншенов на весьма крупных проектах и большом количестве этих экстеншенов. И на практике оказалось, что никаких проблем нет даже когда все экстеншены находятся в пространстве имен прикладного кода. Тип аргумента обычно достаточно селективен, особенно если не навешивать расширения на object. AVK>Да посмотреть даже на сам Fx. Enumerable цепляется к очень распространенному типу, содержит очень большое количество расширений к нему (в фреймворке, наверное, рекордно большое), находится в том же самом неймспейсе, что и все коллекции, т.е. гарантированно попадает в любой код. Получается worst сценарий. Таки и что? Да ничего, все вполне нормально и удобно.
Т.е. всё-таки не в корневом, а в том к чему оно относится.
AVK>С другой стороны, когда у нас все в одном пространстве имен, это добавляет discoverability, которая при разнесении расширений по куче неймспейсов падает стремительным домкратом до уровня обычных статических методов, за что их не попинал только ленивый любитель С++ и свободных функций. И вот это уже реальная, а не теоретическая проблема.
IT>>Как минимум я бы перенёс все расширения куда-нибудь в CodeJam.Extensions.
AVK>И что это даст? Лишний юсинг в прикладном коде?
У меня лично много опыта использования экстеншенов на весьма крупных проектах и большом количестве этих экстеншенов. И на практике оказалось, что с лишним юзингом нет никаких проблем. Но да фиг с ним. Дело не в нём, а в структуре проекта.
IT>> И заодно перетасовал бы файлы в проекте. Соответсвие папок пространсвам имён тоже вроде пока никто не отменял.
AVK>Очень неудобно.
Очень удобно.
AVK>Если у меня классов много — будут неструктурированные длинные списки, если класс только один — дурацкая ситуация папки с одним файлом. ИМХО ну его нафик, средств навигации даже голой студии вполне достаточно, чтобы не искать классы по структуре папок. Я уж не говорю про решарпер.
Навигация дело десятое, хотя и она для кого-то может оказаться важна.
AVK>Пространства имен предназначены для одного — обеспечения отсутствия конфликта имен. Попытка привязать к ним какую то еще ответственность — отличный способ прострелить себе ногу.
Тогда по твоей логике все классы фреймворка нужно было поместить в System. Конфликтов имён там почти нет, а там где они есть можно всегда создать неймспейс, при этом особо не париться и называть их по порядку A, B, C.
В общем, я даже как-то теряюсь от твоей аргументации. Неймспейсы лично для меня всегда были не средством разруливания конфликтов имён, а преждес всего механизмом организации кода проекта, средством устранения свалки всего в одном месте, как ты здесь предлагаешь. Соотвествие папок неймспейсам — это вообще-то соглашение индустриального уровня и уже давно ни у кого не вызывает вопросов. Сейчас же, уверен, у большинства из тех, кто решит посмотреть на код библиотеки, первым делом возникнет сомнение в профессиональном уровне разработчиков, т.к. возникнет ощущение, что тут собрались не профи, а орлята учатся летать.
Для хелперных классов давно уже существует очень простое правило — их следует помещать в неймспейсы с именем неймспейса того класса, для котого делается хелпер. Так для типов String, Type это может быть корневой неймспейс. Для коллекций Collection, для расширений Linq — соответственно Linq. Не думаю, что таких неймспейсов будет много и что это вызовет какие-то сложности при их использовании. Но зато библиотека станет лучше организована, более логична и предсказуема.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
AVK>>Да посмотреть даже на сам Fx. Enumerable цепляется к очень распространенному типу, содержит очень большое количество расширений к нему (в фреймворке, наверное, рекордно большое), находится в том же самом неймспейсе, что и все коллекции, т.е. гарантированно попадает в любой код. Получается worst сценарий. Таки и что? Да ничего, все вполне нормально и удобно.
IT>Т.е. всё-таки не в корневом, а в том к чему оно относится.
Оно прежде всего в томже неймспейсе, что и this аругмент, а не в System.Collections.Generic.Extensions. Я вообще не припомню в фреймворке случая чтобы экстеншены были в отдельном неймспейсе.
IT>У меня лично много опыта использования экстеншенов на весьма крупных проектах и большом количестве этих экстеншенов. И на практике оказалось, что с лишним юзингом нет никаких проблем.
Это лишнее действие, лишняя строка кода.
AVK>>Если у меня классов много — будут неструктурированные длинные списки, если класс только один — дурацкая ситуация папки с одним файлом. ИМХО ну его нафик, средств навигации даже голой студии вполне достаточно, чтобы не искать классы по структуре папок. Я уж не говорю про решарпер. IT>Навигация дело десятое, хотя и она для кого-то может оказаться важна.
Тогда зачем вообще соответствие неймспейсов и папок?
AVK>>Пространства имен предназначены для одного — обеспечения отсутствия конфликта имен. Попытка привязать к ним какую то еще ответственность — отличный способ прострелить себе ногу. IT>Тогда по твоей логике все классы фреймворка нужно было поместить в System.
Нет.
IT> Конфликтов имён там почти нет
Там — нет. А вот в прикладном коде, если бы весь фреймворк был в одном неймспейсе, было бы много просто в силу объема фреймворка. У нас же таких объемов не будет никогда.
При этом, если есть каой то крупный и обособленный кусок — абсолютно согласен ч тем чтобы вытащить его в отдельный неймспейс. См. тот же парсер командной строки — там куча специфичных классов. Поэтому я его и вынес в CodeJam.CmdLine.
А вот выносить в отдельный неймспейс 2-3 функции, или объединять совершенно разнородные методы просто потому что они extension — это какой то процесс ради процесса. К примеру, есть у нас класс Disposable и класс DisposableExtensions. Их надо по разным неймспейсам разнести или как?
Резюмируя — предлагаю вводить новый неймспейс тогда, когда есть хотя бы с десяток классов, тесно и однозначно чем то объединенных. А когда там 2-3 класса на всю тематику, то нефик и сиськи мять, пусть все лежит в корневом.
IT>В общем, я даже как-то теряюсь от твоей аргументации. Неймспейсы лично для меня всегда были не средством разруливания конфликтов имён, а преждес всего механизмом организации кода проекта, средством устранения свалки всего в одном месте, как ты здесь предлагаешь.
А чем тебя в этом качестве не устраивают банальные папки?
IT> Соотвествие папок неймспейсам — это вообще-то соглашение индустриального уровня и уже давно ни у кого не вызывает вопросов.
Регулярно вижу обратное.
IT> Сейчас же, уверен, у большинства из тех, кто решит посмотреть на код библиотеки, первым делом возникнет сомнение в профессиональном уровне разработчиков, т.к. возникнет ощущение, что тут собрались не профи, а орлята учатся летать.
Ага, вот тут еще орлята-ламеры, к примеру, собрались — https://github.com/dotnet/roslyn/tree/master/src/Compilers/Server/PortableServer
Всегда знал что с розлином что то не так.
Ребята из решапрера, кстати, поначалу тоже так как ты считали, но быстро от иллюзий избавились. И сейчас в решарпере связь эта настраиваемая, а не жесткая, а относительно свежие версии еще и научились смотреть на соседние файлики, а не тупо на структуру каталогов.
IT>Для хелперных классов давно уже существует очень простое правило — их следует помещать в неймспейсы с именем неймспейса того класса, для котого делается хелпер.
Т.е. помещаем DisposableExtensions в System?
IT> Так для типов String, Type это может быть корневой неймспейс. Для коллекций Collection, для расширений Linq — соответственно Linq.
Но у IEnumerable неймспейс не Linq, а System.Collections.Generic. У коллекций же их вообще несколько. Как то все очень расплывчато получается.
IT> Не думаю, что таких неймспейсов будет много и что это вызовет какие-то сложности при их использовании.
Это прежде всего лишние сущности, лишние юзинги и снижение discoverability, хз как это по русски.
IT> Но зато библиотека станет лучше организована,
Лучше ли?
IT> более логична и предсказуема.
Обоснуй.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
IT>>Т.е. всё-таки не в корневом, а в том к чему оно относится.
AVK>Оно прежде всего в томже неймспейсе, что и this аругмент, а не в System.Collections.Generic.Extensions. Я вообще не припомню в фреймворке случая чтобы экстеншены были в отдельном неймспейсе.
Extensions имеет смысл, если их туда собрать все. А так следует всё помещать в соответствующие неймспейсы.
IT>>У меня лично много опыта использования экстеншенов на весьма крупных проектах и большом количестве этих экстеншенов. И на практике оказалось, что с лишним юзингом нет никаких проблем. AVK>Это лишнее действие, лишняя строка кода.
Почему лишняя? Очень полезная строка. Позволяет быстро прикинуть, что используется в коде.
AVK>Тогда зачем вообще соответствие неймспейсов и папок?
Затем, что это предсказуемо.
AVK>Там — нет. А вот в прикладном коде, если бы весь фреймворк был в одном неймспейсе, было бы много просто в силу объема фреймворка.
Давай сразу определимся. Мы тут пишем не прикладной код, а библиотеку общего назначение и требования к ней должны быть соответствующие.
AVK>А вот выносить в отдельный неймспейс 2-3 функции, или объединять совершенно разнородные методы просто потому что они extension — это какой то процесс ради процесса. К примеру, есть у нас класс Disposable и класс DisposableExtensions. Их надо по разным неймспейсам разнести или как?
Какая разница сколько там функций? Да хоть одна. Не вижу никаких проблем. Зато искать будет легко и просто.
AVK>Резюмируя — предлагаю вводить новый неймспейс тогда, когда есть хотя бы с десяток классов, тесно и однозначно чем то объединенных. А когда там 2-3 класса на всю тематику, то нефик и сиськи мять, пусть все лежит в корневом.
А если потом к твоим 2-3-м классам добавиться ещё 7-8, то ты их перенесёшь в отдельный неймспейс? Мы тут делаем библиотеку общего назначения, не забыл? С таким подходом у неё нет будущего.
AVK>А чем тебя в этом качестве не устраивают банальные папки?
Навигация в решарпере — это хорошо. Но тот, кто поставит нугет и будет пользоваться этой библиотекой вряд ли будет качать её исходники и включать её в свой проект ради решарпера. Когда мне нужно посмотреть код в какой-то открытой библиотеке и она находится на гитхабе, то я иду туда и ищу нужный класс ориентируясь прежде всего по неймспейсам. Ты эту возможность народу сразу закрываешь, при этом вся твоя аргументация базируется исключительно на вкусовщине.
IT>> Соотвествие папок неймспейсам — это вообще-то соглашение индустриального уровня и уже давно ни у кого не вызывает вопросов. AVK>Регулярно вижу обратное.
Мне тоже доводилось такое видеть. Как правило в таких прокетах чёрт ногу сломит. Давай с самого начала и здесь устроим подобный бардак?
IT>> Сейчас же, уверен, у большинства из тех, кто решит посмотреть на код библиотеки, первым делом возникнет сомнение в профессиональном уровне разработчиков, т.к. возникнет ощущение, что тут собрались не профи, а орлята учатся летать.
AVK>Ага, вот тут еще орлята-ламеры, к примеру, собрались — https://github.com/dotnet/roslyn/tree/master/src/Compilers/Server/PortableServer AVK>Всегда знал что с розлином что то не так.
И что там не так?
AVK>Ребята из решапрера, кстати, поначалу тоже так как ты считали, но быстро от иллюзий избавились. И сейчас в решарпере связь эта настраиваемая, а не жесткая, а относительно свежие версии еще и научились смотреть на соседние файлики, а не тупо на структуру каталогов.
Ещё раз.
1. Мы делаем не конечный продукт на который никогда не появлится не одного референса, а библиотеку общего назначения. Т.е. требования к ней принципиально другие, чем к тому же Решарперу или мелкой утилитке из Рослина.
2. Из каждого правила есть исключения лишь подтверждающие правила. Если есть нормальное логическое обоснование, а не просто личные предпочтения, то всегда можно сделать по-другому. Но не надо это сразу превращать в правило.
IT>>Для хелперных классов давно уже существует очень простое правило — их следует помещать в неймспейсы с именем неймспейса того класса, для котого делается хелпер. AVK>Т.е. помещаем DisposableExtensions в System?
В CodeJam.
Всё касающееся коллекций в CodeJam.Collections.
Linq в CodeJam.Linq.
И так далее по аналогии. Т.е. вместо System ставим CodeJam. Ещё я бы не стал всё, касающееся коллекций запихивать в соостветствующие неймспейсы. Collections вполне достаточно.
IT>> Так для типов String, Type это может быть корневой неймспейс. Для коллекций Collection, для расширений Linq — соответственно Linq.
AVK>Но у IEnumerable неймспейс не Linq, а System.Collections.Generic. У коллекций же их вообще несколько. Как то все очень расплывчато получается.
Это как раз то самое исключение.
IT>> Не думаю, что таких неймспейсов будет много и что это вызовет какие-то сложности при их использовании. AVK>Это прежде всего лишние сущности, лишние юзинги и снижение discoverability, хз как это по русски.
Ты же решарпером пользуещься, там это без проблем.
IT>> более логична и предсказуема. AVK>Обоснуй.
Размещая расширения в произвольных папках ты только путаешь тех, кто будет изучать код библиотеки. Открыв проект и увидев папку String первое, что мне придёт в голову, что есть такой namespace CodeJam.String. Или наоборот, если я захочу посмотреть на гитхабе код StringExtensions.Substring, то искать я его буду в корне и очень сильно удивлюсь не найдя его там. И придётся мне с матом бродить по всем папкам. Что касается строк, то проявив смекалку я может быть быстро дойду до папки String, но вот с тем же CharExtensions.IsDigit уже могут быть проблемы.
Далее. Как я уже говорил, критерий выноса кода в отдельный неймспейс по количеству файлов приведёт либо к бардаку, либо к ломке совместимости в будущем, т.е. ни к чему хорошему.
Наличие открытых неймспейсов в коде — это не лишная, а очень даже полезная информация, которая лично мне сразу даёт представление с чем в данном файле придётся столкнуться. Поэтому увидев в коде using CodeJam.Collections; мне уже будет примерно понятно с чем я тут буду иметь дело.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
AVK>>Оно прежде всего в томже неймспейсе, что и this аругмент, а не в System.Collections.Generic.Extensions. Я вообще не припомню в AVK>>Это лишнее действие, лишняя строка кода. IT>Почему лишняя? Очень полезная строка. Позволяет быстро прикинуть, что используется в коде.
Сомнительное достоинство.
AVK>>Тогда зачем вообще соответствие неймспейсов и папок? IT>Затем, что это предсказуемо.
Но неудобно.
AVK>>Там — нет. А вот в прикладном коде, если бы весь фреймворк был в одном неймспейсе, было бы много просто в силу объема фреймворка. IT>Давай сразу определимся. Мы тут пишем не прикладной код, а библиотеку общего назначение и требования к ней должны быть соответствующие.
Еще раз. В фреймворке очень много типов, поэтому один неймспейс обладал бы очень высокой вероятностью порождения конфликтов. У нас типов вряд ли будет сильно больше чем в каком нибудь System.Windows.Forms, так что и подобной проблемы тоже нет.
IT>Какая разница сколько там функций?
Большая. Неймспейс становится бесполезным в качестве средства организации и порождает ненужные развесистые деревья каталогов. Мне в свое время хватило жабы с ее жесткой привязкой каталогов к неймспейсам. Независимая структура намного удобнее — МС вполне правильно и осознанно ввели директиву namespace с самого начала.
IT> Да хоть одна. Не вижу никаких проблем. Зато искать будет легко и просто.
Искать и так легко и просто, вызвав Find Symbol.
IT>А если потом к твоим 2-3-м классам добавиться ещё 7-8, то ты их перенесёшь в отдельный неймспейс?
Вероятность такого близка к 0. У нас все таки не большие и сложные вещи предполагаются, которые могут неузнаваемо эволюционировать со временем.
AVK>>А чем тебя в этом качестве не устраивают банальные папки? IT>Навигация в решарпере — это хорошо. Но тот, кто поставит нугет и будет пользоваться этой библиотекой вряд ли будет качать её исходники и включать её в свой проект ради решарпера.
Тот кто ее поставит — ему вообще будет покласть на структуру папок.
IT> Когда мне нужно посмотреть код в какой-то открытой библиотеке и она находится на гитхабе, то я иду туда и ищу нужный класс ориентируясь прежде всего по неймспейсам.
А я пользуюсь поиском, так быстрее. А если просто глазком взглянуть — просто смотрю декомпилят решарпера.
AVK>>Регулярно вижу обратное. IT>Мне тоже доводилось такое видеть. Как правило в таких прокетах чёрт ногу сломит. Давай с самого начала и здесь устроим подобный бардак?
Я не считаю это бардаком. Я писал код в том числе и в крупных проектах, и никаких проблем по поводу несоответствия каталогов не испытывал. А вот когда лет 10-15 назад пытались форсить их соответствие, вот тогда это мне сильно мешало.
IT>И что там не так?
Нет точного соответствия папок неймспейсам. Если логическая группировка файлов по фолдерам, но никакой аналогичной группировки по неймспейсам. Так что там с твоими сомнениями в профессиональном уровне разработчиков розлина?
IT>1. Мы делаем не конечный продукт на который никогда не появлится не одного референса, а библиотеку общего назначения.
Еще раз — пользователям библиотеки насрать на организацию файлов по каталогам. Твой пример с ручным поиском по каталогу исходников сильно натянут. Если тебе так уж сильно хочется — можно вообще в автогенеренном хелпе вставить прямую ссылку на исходник. Или поднять source server или воспользоваться готовым, тогда вообще можно будет в студии одним кликом смотреть, да еще и отлаживаться при необходимости.
IT>2. Из каждого правила есть исключения лишь подтверждающие правила.
С этим ты к Владу сходи, он объяснит.
IT> Если есть нормальное логическое обоснование, а не просто личные предпочтения, то всегда можно сделать по-другому. Но не надо это сразу превращать в правило.
Можно теперь попонятнее объяснить, что ты этой фразой хотел сказать? Я вроде понятно объяснил — мне не нравятся лишние ограничения на структуру каталогов, они мне мешают делать эту структуру такой, какой мне хочется. А ты мне какие то асбтракции про исключения и правила втираешь.
IT>>>Для хелперных классов давно уже существует очень простое правило — их следует помещать в неймспейсы с именем неймспейса того класса, для котого делается хелпер. AVK>>Т.е. помещаем DisposableExtensions в System?
IT>В CodeJam.
Почему именно туда?
IT>Всё касающееся коллекций в CodeJam.Collections.
А почему не в CodeJam.Collections.Generic? Или часть, касающуюся массивов в CodeJam, часть в CodeJam.Enumerable, а часть в CodeJam.Collection?
Я тут еще одну прекрасную вещь про много неймспейсов вспомнил. Ты же помнишь, что называть класс так же, как и часть неймспейса мягко говоря не рекомендуется?
IT>Linq в CodeJam.Linq.
А что такое Linq формально? Вот Concat который у нас — это LINQ? А DisposeAll это LINQ?
IT>И так далее по аналогии.
Я по прежнему не вижу здесь формальной системы.
IT>Т.е. вместо System ставим CodeJam.
Тогда почему не CodeJam.Collections.Generic? И откуда взялся Linq, если в виде неймспейса он только в Xml.Linq?
IT> Ещё я бы не стал всё, касающееся коллекций запихивать в соостветствующие неймспейсы. Collections вполне достаточно.
Вот вот. Все к тому и сводится, что не надо себя ограничивать формализмами там, где в них нет крайней необходимости.
AVK>>Но у IEnumerable неймспейс не Linq, а System.Collections.Generic. У коллекций же их вообще несколько. Как то все очень расплывчато получается. IT>Это как раз то самое исключение.
Ну то есть теория не работает, давай заткнем дырку красивой пословицей? Или все таки признаем, что не надо себя в ненужные рамки загонять?
IT>>> Не думаю, что таких неймспейсов будет много и что это вызовет какие-то сложности при их использовании. AVK>>Это прежде всего лишние сущности, лишние юзинги и снижение discoverability, хз как это по русски. IT>Ты же решарпером пользуещься, там это без проблем.
Что там без проблем? Вот сейчас я пишу using CodeJam и при нажатии на точку вижу все расширения. А если раскидать все по неймспейсам, так мне придется вспоминать что в какой неймспейсе находится, либо смотреть список вообще без разграничений по неймспейсам. А вот так чтобы попросить его контекстно показать мне список мемберов в неймспейсе CodeJam.*, такого он пока не умеет, только список типов.
IT>>> более логична и предсказуема. AVK>>Обоснуй. IT>Размещая расширения в произвольных папках
Они не произвольные, не надо гипертрофировать. Они просто связаны с неймспейсами нежестко. Я даже согласен на правило, что в одной папке не может быть разных неймспейсов, это вполне нормально и логично. Но вот чтобы я не мог создать подпапки для группировки части файлов, не создавая лишних неймспейсов — тут я не согласен.
Пример розлина я уже приводил. Посмотри теперь в проекте experimental — там есть папка CmdLine.Model.Checking, причем типы там публичные. Ну вот удобно мне так при разработке — поместить этот кусочек модели в отдельную подпапку. А вот нафига при этом еще и в CodeJam.CmdLine.Model.Checking типы засовывать, а потом плодить стадо юзингов и внутри кода библиотеки, и внутри прикладного кода — это мне непонятно.
Лично у меня эвристика папочная простая. Если нужно несколько неймспейсов в одном проекте (потребность в неймспейсе при этом первична и не имеет никакого отношения к папкам) — завожу для каждого отдельную папку. В 95% случаев создавать неймспейсы 3 уровня не требуется. Далее, внутри папок или корня проекта с одним неймспейсом, если вдруг образуется больше двух тесно связанных между собой файлов (не обязательно исходников! ресурсы, картинки и т.п. тоже считаются) — завожу для них отдельную папочку без образования неймспейса. И уж точно боже упаси для группировки пихать несколько типов в один файл.
IT> ты только путаешь тех, кто будет изучать код библиотеки. Открыв проект и увидев папку String первое, что мне придёт в голову, что есть такой namespace CodeJam.String. Или наоборот, если я захочу посмотреть на гитхабе код StringExtensions.Substring, то искать я его буду в корне и очень сильно удивлюсь не найдя его там. И придётся мне с матом бродить по всем папкам. Что касается строк, то проявив смекалку я может быть быстро дойду до папки String, но вот с тем же CharExtensions.IsDigit уже могут быть проблемы.
А как надо? Если использовать то, что ты предлагаешь, то надо и StringExtensions, и CharExtensions кидать в корень, рядом с Disposable, DisposableExtensions, парочкой файлов Fn. Туда же до кучи намешать из коллекций те методы, у которых в параметрах массивчик. Полученная каша правда удобнее? Или это очередное исключение?
IT>Далее. Как я уже говорил, критерий выноса кода в отдельный неймспейс по количеству файлов приведёт либо к бардаку, либо к ломке совместимости в будущем, т.е. ни к чему хорошему.
Ломка совместимости это как раз когда упираться рогом и пытаться на каждый фолдер заводить неймспейс. А бардака никакого не будет, если каталоги не от балды заводить, а с умом.
IT>Наличие открытых неймспейсов в коде — это не лишная, а очень даже полезная информация, которая лично мне сразу даёт представление с чем в данном файле придётся столкнуться.
Ну а лично я туда никогда не заглядываю. Как то информация об использовании чего то в файле не очень интересна — файл почти не фигурирует как значимая сущность при анализе кода.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
IT>>Почему лишняя? Очень полезная строка. Позволяет быстро прикинуть, что используется в коде. AVK>Сомнительное достоинство.
Офигительное достоинство, если много работаешь с чужим кодом, а не только со своим.
AVK>>>Тогда зачем вообще соответствие неймспейсов и папок? IT>>Затем, что это предсказуемо. AVK>Но неудобно.
Тебе может и не удобно. Или ты этот проект затеял исключительно для себя?
AVK>Еще раз. В фреймворке очень много типов, поэтому один неймспейс обладал бы очень высокой вероятностью порождения конфликтов. У нас типов вряд ли будет сильно больше чем в каком нибудь System.Windows.Forms, так что и подобной проблемы тоже нет.
Т.е. у нас будет всего немного. Ага. Ставим сюда закладку.
IT>>Какая разница сколько там функций?
AVK>Большая. Неймспейс становится бесполезным в качестве средства организации и порождает ненужные развесистые деревья каталогов. Мне в свое время хватило жабы с ее жесткой привязкой каталогов к неймспейсам. Независимая структура намного удобнее — МС вполне правильно и осознанно ввели директиву namespace с самого начала.
Тем не менее MS не часто отходит от правила "один неймспейс — один фолдер".
IT>> Да хоть одна. Не вижу никаких проблем. Зато искать будет легко и просто. AVK>Искать и так легко и просто, вызвав Find Symbol.
Ещё раз. Это если у тебя есть Find Symbol, а если у тебя есть только браузер, то не легко и не просто.
IT>>А если потом к твоим 2-3-м классам добавиться ещё 7-8, то ты их перенесёшь в отдельный неймспейс? AVK>Вероятность такого близка к 0. У нас все таки не большие и сложные вещи предполагаются, которые могут неузнаваемо эволюционировать со временем.
Ой я тебя умоляю. Если есть вероятность чего-то плохого, то это обязательно произойдёт. Ты как будто не программист.
AVK>Я не считаю это бардаком. Я писал код в том числе и в крупных проектах, и никаких проблем по поводу несоответствия каталогов не испытывал. А вот когда лет 10-15 назад пытались форсить их соответствие, вот тогда это мне сильно мешало.
А я считаю это самым натуральным бардаком. В библиотеке 3 класса, а найти что-нибудь в ней может только тот, кто их писал. Афигенный порядок.
IT>>И что там не так? AVK>Нет точного соответствия папок неймспейсам.
Да там всего три файла в одном неймспейсе, какие папки?
IT>>1. Мы делаем не конечный продукт на который никогда не появлится не одного референса, а библиотеку общего назначения. AVK>Еще раз — пользователям библиотеки насрать на организацию файлов по каталогам.
Пока, глядя не нелогичность структуры проекта можно сделать вывод, что это разработчикам библиотеке насрать на их потенциальных пользователей.
IT>>2. Из каждого правила есть исключения лишь подтверждающие правила. AVK>С этим ты к Владу сходи, он объяснит.
О, да. Как раз у нас Влад большой любитель прогибать логику под свои предпочтения.
IT>> Если есть нормальное логическое обоснование, а не просто личные предпочтения, то всегда можно сделать по-другому. Но не надо это сразу превращать в правило. AVK>Можно теперь попонятнее объяснить, что ты этой фразой хотел сказать? Я вроде понятно объяснил — мне не нравятся лишние ограничения на структуру каталогов, они мне мешают делать эту структуру такой, какой мне хочется. А ты мне какие то асбтракции про исключения и правила втираешь.
Объясняю. Ограничения существуют, чтобы им следовали, не обязательно жёстко, но следовали. А для тебя похоже они существуют исключительно, чтобы их сразу нарушать.
IT>>>>Для хелперных классов давно уже существует очень простое правило — их следует помещать в неймспейсы с именем неймспейса того класса, для котого делается хелпер. AVK>>>Т.е. помещаем DisposableExtensions в System?
IT>>В CodeJam. AVK>Почему именно туда?
А что здесь непонятног?
IT>>Всё касающееся коллекций в CodeJam.Collections. AVK>А почему не в CodeJam.Collections.Generic?
Можно и туда, но думаю, CodeJam.Collections достаточно.
AVK>Я тут еще одну прекрасную вещь про много неймспейсов вспомнил. Ты же помнишь, что называть класс так же, как и часть неймспейса мягко говоря не рекомендуется?
Не помню.
IT>>Linq в CodeJam.Linq. AVK>А что такое Linq формально? Вот Concat который у нас — это LINQ? А DisposeAll это LINQ?
Чего эти классы хелперы?
AVK>Тогда почему не CodeJam.Collections.Generic? И откуда взялся Linq, если в виде неймспейса он только в Xml.Linq?
Откуда?
IT>> Ещё я бы не стал всё, касающееся коллекций запихивать в соостветствующие неймспейсы. Collections вполне достаточно. AVK>Вот вот. Все к тому и сводится, что не надо себя ограничивать формализмами там, где в них нет крайней необходимости.
Судя по твоим рассуждениям у тебя вообще нет ниобходимости ни в каких правилах. Это как раз то, что я называл нелогичностью и непредсказуемостью. И это делается с самого начала, а что будет дальше?
AVK>Ну то есть теория не работает, давай заткнем дырку красивой пословицей? Или все таки признаем, что не надо себя в ненужные рамки загонять?
Ну не надо рамок, так нк надо. Один местный проект без рамок у нас уже есть.
AVK>Пример розлина я уже приводил.
В том примере три класса по 20 строчек и один неймспейс.
AVK>Посмотри теперь в проекте experimental — там есть папка CmdLine.Model.Checking, причем типы там публичные. Ну вот удобно мне так при разработке — поместить этот кусочек модели в отдельную подпапку. А вот нафига при этом еще и в CodeJam.CmdLine.Model.Checking типы засовывать, а потом плодить стадо юзингов и внутри кода библиотеки, и внутри прикладного кода — это мне непонятно.
Посмотрел. Похоже в CmdLine неслабый монстрик зарождается. Там делов максимум на 200 строк кода, а у нас уже 3 папки и 25 классов. Даже не знаю что тут и посоветовать.
Кстати, от подобной практики, когда модель убирается в отдельную папку я уже давно отказался даже в WPF. На практике крайне не удобно бегать из папки в папку, работая по сути над одной и той же вещью.
AVK>А как надо? Если использовать то, что ты предлагаешь, то надо и StringExtensions, и CharExtensions кидать в корень, рядом с Disposable, DisposableExtensions, парочкой файлов Fn. Туда же до кучи намешать из коллекций те методы, у которых в параметрах массивчик. Полученная каша правда удобнее? Или это очередное исключение?
Я вообще не вижу смысла разбивать расширения со строками и символами на пять файлов. Всё можно поместить в один, а группы методов разделаить регионами и, опаньки, проблема с папкой исчезает сама собой.
AVK>Ломка совместимости это как раз когда упираться рогом и пытаться на каждый фолдер заводить неймспейс. А бардака никакого не будет, если каталоги не от балды заводить, а с умом.
Да бардак уже есть. При этом базируется он на твоих рассуждениях. в которых я никак не уловлю логики. С одной стороны ты говоришь, что у нас в проекте классов будет немного, поэтому неймспейсы не нужны. С другой, у нас много файлов, поэтому нужны папки.
Короче. Обсуждать это я больше не намерен, т.к. похоже, что стороны пришли к взаимному несогласию и дальшее обсуждени лишено всякого смысла. Делай как считаешь нужным.
Если нам не помогут, то мы тоже никого не пощадим.