Нет, тут как раз все правильно. Надо четко понимать, что свойства MSBuild и свойства проекта в VS — это две совершенно разные вещи, которые иногда пересекаются как деталь реализации данного конкретного типа проектов.
>> А в чем отличия этой Common Project System от стандартной системы сборки проектов в MSBuild? И почему декларативное описание свойств не будет работать? Мсбилд всегда так работает, ну или я не правильно понимаю ваше высказывание.
Тут мне придется разлиться мысию по древу, немного определиться с терминологией, и углубиться в историю.
С точки зрения MSBuild, «проект» — это просто корневой скрипт системы сборки, точка входа в неё. Никакого другого смысла в него не вкладывается, и обычные VS-термины вроде «файлов проекта» или там «выходной сборки» на этом уровне смысла не имеют. Есть просто набор properties (по сути, скалярных переменных), items (коллекций), и targets (функций), который выполняется. Все.
С точки зрения VS, «проект» — это отнюдь не MSBuild-скрипт, и даже вообще не обязательно файл. Это просто некоторый COM-объект в памяти, реализующий интерфейсы IVsProject и IVsHierarchy, и ряд связанных с ними. Соответственно, «проектная система» (project system) — это реализация конкретной фабрики (IVsProjectFactory) для создания таких объектов, и реализации этих самых объектов для этой конкретной фабрики. Вся эта система очень абстрактна, и то, как именно реализован проект под капотом, может сильно варьироваться, в т.ч. и откуда грузится при открытии проекта, и куда пишется при сохранении. На практике постепенно пришли к единому знаменателю в виде MSBuild-скриптов, чтобы логика билда, по крайней мере, у всех проектных систем была одна.
При этом реализация всего остального в проектной системе (т.е. собственно IVsProject и IVsHierarchy — интерфейсы, ответственные за наполнение Solution Explorer, открытие редакторов для документов etc) по прежнему различается. В частности, если взять тот же VS 2010, то в нем C++ — это одна реализация (что забавно, написанная на C#), C# и VB — совершенно другая (что еще более забавно, написанная на C++), F# — третья (форк MPF — примера по написанию проектной системы из VS SDK), Setup project — четвертая. Если ставить расширения, то, например, Python Tools и Node.js Tools — это будет пятая (тоже форк MPF, но не имеет родства с C#), PHP Tools — шестая (форк PTVS), RemObjects Oxygene — седьмая (что-то свое, но, кажется, тоже форк MPF). Плюс есть всякие мелкие вспомогательные проектные системы, не привязанные к языкам, и не имеющие смысла сами по себе — например, Cloud Service Project в Azure SDK.
Понятно, что подобный зоопарк приводит к головной боли в виде необходимости реализовывать одни и те же фичи по десять раз. Поэтому периодически предпринимаются попытки написать одну универсальную проектную систему, которая покроет все требования, и может быть использована и кастомизирована всеми языками под свои нужды. Как правило, это работало примерно так, как описано в xkcd про стандарты (например, проектная система C#/VB была именно такой попыткой, но в итоге её никто больше использовать не стал). К VS 2010 очередной попыткой стал CPS, который вырос из переписывания проектной системы C++ (старая не использовала MSBuild, поэтому её все равно надо было переделывать). Попыткой, похоже, успешной, потому как его подхватали JS, и теперь вот .NET Core.
Возвращаясь к терминологии — с точки зрения VS самой по себе (не включая стандартные проектные системы), понятия «свойства проекта» в общем случае не существует. Есть фиксированный набор свойств у корневой иерархии проекта (IVsHierarchy), есть понятие «конфигурация» (IVsCfg) и «платформа», и, в общем-то, все. Все остальное — это штуки, специфичные для каждой проектной системы, и какие они вообще есть (и есть ли!), и где и как хранятся — решает именно она. На практике, опять же, есть некоторые общие вещи вроде выходного файла, но даже для них в общем случае нет одного универсального интерфейса, через который их можно получить из любого произвольного проекта. Есть IVsBuildPropertyStorage (который появился одновременно с MSBuild и проектной системой для С#/VB на его основе), который поддерживают все MSBuild-based проектные системы — но, в принципе, они это делать не обязаны.
Графический интерфейс для редактирования этих свойств тоже реализуется проектной системой. VS здесь предоставляет костыли в виде реализации COM property pages, но каждая конкретная страница целиком и полностью на откупе у проектной системы.
Для систем, которые в качестве файлового формата для проекта используют MSBuild, наиболее очевидный маппинг свойств на файл — это MSBuild properties (а для файлов проекта — соответственно, MSBuild items). Обратное неверно, т.е. далеко не каждое свойство в MSBuild является свойством проекта в данной системе, и не каждый item является файлом проекта. Собственно, если сделать дамп свойств после чтения какого-нибудь шарпного или плюсового проекта, их там будет с пару сотен, и из них только несколько десятков видны в VS как свойства проекта. Остальное — по сути, просто временные переменные. Что есть что, решает опять же проектная система.
Так вот, в случае с CPS, это решение не зашито в код системы, как во всех остальных случаях, а вынесено в декларативные описания в сам MSBuild-скрипт. Т.е. файл проекта, а точнее, импортируемые им .targets и .props файлы, описывают, как его надо интерпретировать, и в частности, какие именно MSBuild-свойства должны быть отображены в UI, и каким именно образом. Это как раз и есть PropertyPageSchema, и используемые им XML-файлы (которые на самом деле XAML). И вся эта машинерия — специфична именно для CPS, и работает только с его проектами. К MSBuild она прямого отношения не имеет, и последний рассматривает её просто как обычный набор свойств и items, никак ни с чем не связанный и не имеющий никакого сакрального смысла. В сборке, соответственно, она тоже не участвует.
Описанный вами способ добавления свойств — это не MSBuild вообще, а конкретно те виды проектов, которые построены на Common Project System (это проектная система, изначально появившаяся в VS 2010 для C++-проектов, а на сегодня используется также для WinStore JavaScript проектов, и .NET vNext / Project K / .kproj). Для обычных C#/VB проектов, например, это работать не будет. Для F#, Python, Node.js, PHP — тоже. Тут та же проблема — каждая проектная система реализует эти штуки сама и по-своему; в CPS сделали такое вот декларативное описание пропертей, в других — что-то еще.
В C# добавить свои свойства вполне можно, но там придется еще рисовать руками property page для их редактирования, и в целом это все будет выглядеть совсем по-другому.
«Любой проект Microsoft Visual Studio является скриптом MSBuild» — не совсем так. Все «коробочные» типы проектов в VS являются MSBuild-скриптами, это да. Но исторически это было не так (VC++ до VS2010 имел свой формат, и еще был Setup project), и в общем случае это некорректно, т.к. формат файла проекта отдается целиком на откуп проектной системе (project system — компоненту, отвечающему за загрузку и работу с данным конкретном типа проекта).
Да, можно — в [expr.add]:
«For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.»
Но вообще это все на самом деле очень мутная тема. Например, непонятно даже, валиден ли указатель, если он указывает на что-то валидное внутри массива, но был получен арифметикой из другого массива, даже если стандарт гарантирует непрерывное размещение в памяти. Например, если есть:
int a[2][3];
И мы взяли указатель на &a[0][2], а потом сдвинули его на два элемента вперед. По логике вещей, мы должны попасть в &a[1][1], и стандарт гарантирует именно такое размещение в пемяти. Но ведь исходный указатель был взят от массива a[0], и в стандарте есть этот параграф, который явно запрещает сдвигать его за пределы (плюс один элемент в конце), т.е. вроде как это UB. На эту тему в comp.std.c++ был длинный тред несколько лет назад, но в итоге консенсуса не было.
Выше есть ветка, где это разобрано. Как минимум в C++, стандарт гарантирует, что в массиве элементы идут последовательно, и нет дырок и padding в начале и конце.
Я бы не советовал так упрощать lvalues и сводить их к ссылкам (а равно и к присваиванию, это уже чисто сишная заморочка). Это все-таки не одно и тоже, и в стандарте эта разница имеет значение. Иначе потом будет путаница с временными объектами, operator=, и rvalue references.
> Так дело в том, что раньше мы были избавлены от подобного для нестатических методов. А теперь и для них тоже придется смотреть.
Не совсем понял, о чем это. Вызов вида WriteLine() вполне может вызвать и статический метод сегодня (если он на вашем классе). Вы имеете в виду неквалифицированные вызовы вообще?
Я не вижу особой проблемы с тем, чтобы посмотреть. Если вы видите что-то непонятное, вроде Foo(), то вам в любом случае придется смотреть, что оно делает, и неважно, в вашем оно классе, или нет (и сама по себе информация о том, это instance или static метод, ничего важного не несет).
Тут мне придется разлиться мысию по древу, немного определиться с терминологией, и углубиться в историю.
С точки зрения MSBuild, «проект» — это просто корневой скрипт системы сборки, точка входа в неё. Никакого другого смысла в него не вкладывается, и обычные VS-термины вроде «файлов проекта» или там «выходной сборки» на этом уровне смысла не имеют. Есть просто набор properties (по сути, скалярных переменных), items (коллекций), и targets (функций), который выполняется. Все.
С точки зрения VS, «проект» — это отнюдь не MSBuild-скрипт, и даже вообще не обязательно файл. Это просто некоторый COM-объект в памяти, реализующий интерфейсы IVsProject и IVsHierarchy, и ряд связанных с ними. Соответственно, «проектная система» (project system) — это реализация конкретной фабрики (IVsProjectFactory) для создания таких объектов, и реализации этих самых объектов для этой конкретной фабрики. Вся эта система очень абстрактна, и то, как именно реализован проект под капотом, может сильно варьироваться, в т.ч. и откуда грузится при открытии проекта, и куда пишется при сохранении. На практике постепенно пришли к единому знаменателю в виде MSBuild-скриптов, чтобы логика билда, по крайней мере, у всех проектных систем была одна.
При этом реализация всего остального в проектной системе (т.е. собственно IVsProject и IVsHierarchy — интерфейсы, ответственные за наполнение Solution Explorer, открытие редакторов для документов etc) по прежнему различается. В частности, если взять тот же VS 2010, то в нем C++ — это одна реализация (что забавно, написанная на C#), C# и VB — совершенно другая (что еще более забавно, написанная на C++), F# — третья (форк MPF — примера по написанию проектной системы из VS SDK), Setup project — четвертая. Если ставить расширения, то, например, Python Tools и Node.js Tools — это будет пятая (тоже форк MPF, но не имеет родства с C#), PHP Tools — шестая (форк PTVS), RemObjects Oxygene — седьмая (что-то свое, но, кажется, тоже форк MPF). Плюс есть всякие мелкие вспомогательные проектные системы, не привязанные к языкам, и не имеющие смысла сами по себе — например, Cloud Service Project в Azure SDK.
Понятно, что подобный зоопарк приводит к головной боли в виде необходимости реализовывать одни и те же фичи по десять раз. Поэтому периодически предпринимаются попытки написать одну универсальную проектную систему, которая покроет все требования, и может быть использована и кастомизирована всеми языками под свои нужды. Как правило, это работало примерно так, как описано в xkcd про стандарты (например, проектная система C#/VB была именно такой попыткой, но в итоге её никто больше использовать не стал). К VS 2010 очередной попыткой стал CPS, который вырос из переписывания проектной системы C++ (старая не использовала MSBuild, поэтому её все равно надо было переделывать). Попыткой, похоже, успешной, потому как его подхватали JS, и теперь вот .NET Core.
Возвращаясь к терминологии — с точки зрения VS самой по себе (не включая стандартные проектные системы), понятия «свойства проекта» в общем случае не существует. Есть фиксированный набор свойств у корневой иерархии проекта (IVsHierarchy), есть понятие «конфигурация» (IVsCfg) и «платформа», и, в общем-то, все. Все остальное — это штуки, специфичные для каждой проектной системы, и какие они вообще есть (и есть ли!), и где и как хранятся — решает именно она. На практике, опять же, есть некоторые общие вещи вроде выходного файла, но даже для них в общем случае нет одного универсального интерфейса, через который их можно получить из любого произвольного проекта. Есть IVsBuildPropertyStorage (который появился одновременно с MSBuild и проектной системой для С#/VB на его основе), который поддерживают все MSBuild-based проектные системы — но, в принципе, они это делать не обязаны.
Графический интерфейс для редактирования этих свойств тоже реализуется проектной системой. VS здесь предоставляет костыли в виде реализации COM property pages, но каждая конкретная страница целиком и полностью на откупе у проектной системы.
Для систем, которые в качестве файлового формата для проекта используют MSBuild, наиболее очевидный маппинг свойств на файл — это MSBuild properties (а для файлов проекта — соответственно, MSBuild items). Обратное неверно, т.е. далеко не каждое свойство в MSBuild является свойством проекта в данной системе, и не каждый item является файлом проекта. Собственно, если сделать дамп свойств после чтения какого-нибудь шарпного или плюсового проекта, их там будет с пару сотен, и из них только несколько десятков видны в VS как свойства проекта. Остальное — по сути, просто временные переменные. Что есть что, решает опять же проектная система.
Так вот, в случае с CPS, это решение не зашито в код системы, как во всех остальных случаях, а вынесено в декларативные описания в сам MSBuild-скрипт. Т.е. файл проекта, а точнее, импортируемые им .targets и .props файлы, описывают, как его надо интерпретировать, и в частности, какие именно MSBuild-свойства должны быть отображены в UI, и каким именно образом. Это как раз и есть PropertyPageSchema, и используемые им XML-файлы (которые на самом деле XAML). И вся эта машинерия — специфична именно для CPS, и работает только с его проектами. К MSBuild она прямого отношения не имеет, и последний рассматривает её просто как обычный набор свойств и items, никак ни с чем не связанный и не имеющий никакого сакрального смысла. В сборке, соответственно, она тоже не участвует.
В C# добавить свои свойства вполне можно, но там придется еще рисовать руками property page для их редактирования, и в целом это все будет выглядеть совсем по-другому.
www.wired.com/2015/02/science-one-agrees-color-dress/
«For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.»
Но вообще это все на самом деле очень мутная тема. Например, непонятно даже, валиден ли указатель, если он указывает на что-то валидное внутри массива, но был получен арифметикой из другого массива, даже если стандарт гарантирует непрерывное размещение в памяти. Например, если есть:
И мы взяли указатель на &a[0][2], а потом сдвинули его на два элемента вперед. По логике вещей, мы должны попасть в &a[1][1], и стандарт гарантирует именно такое размещение в пемяти. Но ведь исходный указатель был взят от массива a[0], и в стандарте есть этот параграф, который явно запрещает сдвигать его за пределы (плюс один элемент в конце), т.е. вроде как это UB. На эту тему в comp.std.c++ был длинный тред несколько лет назад, но в итоге консенсуса не было.
typeid() с вами не согласен, кстати.
(в смысле, тип-то у них действительно один, но это не int&)
Что до RPi, обратите внимание, что все анонсы идут в контексте IoT.
Не совсем понял, о чем это. Вызов вида WriteLine() вполне может вызвать и статический метод сегодня (если он на вашем классе). Вы имеете в виду неквалифицированные вызовы вообще?
Я не вижу особой проблемы с тем, чтобы посмотреть. Если вы видите что-то непонятное, вроде Foo(), то вам в любом случае придется смотреть, что оно делает, и неважно, в вашем оно классе, или нет (и сама по себе информация о том, это instance или static метод, ничего важного не несет).
На самом деле вполне нормально, если не писать функции на два экрана :)