web-dev-qa-db-fra.com

Différence entre .Net Core, Portable, Standard, Compact, UWP et PCL?

J'ai entendu parler

  • .Net Core
  • .Net Portable
  • Norme .Net
  • .Net Compact
  • Plateforme Windows universelle
  • Bibliothèques de classes portables

Tous ces éléments m'ont été expliqués comme "un sous-ensemble du .Net complet qui vous permet de cibler plusieurs plates-formes" . Donc mes questions sont

  1. Quelle est la différence!?
  2. Si je veux écrire une bibliothèque utilisable pour un public aussi large que possible, laquelle (ou plusieurs) de celles-ci dois-je besoin d'utiliser?

(Ma situation spécifique: j'ai ne bibliothèque qui cible .Net 2.0, .Net 4.5 et UWP. Pour cibler UWP, il fallait créer un nouveau projet VS et lier tous les fichiers existants , ce qui est une énorme douleur. Maintenant, quelqu'un me dit que cela ne fonctionne pas pour PCL, et d'après le son, je dois recommencer pour .Net Standard!?)

Je répondrai d'abord à votre deuxième question:

J'ai une bibliothèque qui cible .Net 2.0, .Net 4.5 et UWP. Le ciblage de l'UWP a nécessité la création d'un nouveau projet VS et la liaison de tous les fichiers existants, ce qui est une énorme douleur. Maintenant, quelqu'un me dit que cela ne fonctionne pas pour PCL, et à en juger par le son, je dois recommencer pour .Net Standard !?)

Si je veux écrire une bibliothèque utilisable pour un public aussi large que possible, laquelle (ou plusieurs) dois-je utiliser?

Réponse courte: vous devez cibler netstandard. Utilisez le version la plus basse qui possède toutes les API dont vous avez besoin. Vous pouvez utiliser un outil comme Port API à vérifiez la compatibilité de votre projet existant avec une version netstandard donnée .

Malheureusement, cette approche laissera des plates-formes plus anciennes, dans votre cas, .NET 2.0. Si le maintien de la prise en charge de .NET 2.0 est nécessaire, vous aurez besoin d'un projet distinct (avec des fichiers liés) pour créer un assembly .NET 2.0 distinct.

Passons aux détails ...

Quelle est la différence!?

  • . Net Standard (netstandard) - il s'agit de la nouvelle API BCL multiplateforme. C'est un "standard" dans le sens où c'est juste une définition d'API et non une implémentation. L'idée est que vous pouvez compiler votre bibliothèque vers (une version de) cette API et elle s'exécutera sur n'importe quelle plate-forme qui prend en charge cette version.
  • . Net Core - vous pouvez le considérer comme une implémentation de référence de netstandard (avec quelques bits supplémentaires). C'est une multiplateforme implémentation de cette API. Il est possible que des interfaces utilisateur et d'autres cadres puissent s'appuyer dessus, mais pour l'instant, son seul point d'ancrage sûr agit comme la plate-forme de choix pour ASP.NET Core. [Note latérale: pour des raisons historiques, ".NET Core" est complètement différent que la cible netcore NuGet; lorsque vous êtes dans un contexte NuGet, netcore signifie "Windows 8/8.1/10"] .
  • . Net Portable et Bibliothèques de classes portables - Bibliothèques de classes portables (PCL) sont une approche du plus petit dénominateur commun pour fournir une API multiplateforme. Ils couvrent un large éventail de plates-formes cibles , mais ils sont incomplets et non pérennes. Ils ont été essentiellement remplacés par netstandard.
  • . Net Compact - Il s'agit d'un framework .NET complètement différent avec sa propre API unique. Il est complètement incompatible avec toute autre version de framework, PCL ou netstandard; en tant que tel, il est beaucoup plus difficile à prendre en charge que toute autre plate-forme. Cependant, il est toujours utilisé sur les appareils avec des contraintes de mémoire strictes.
  • Plateforme Windows universelle - Il s'agissait d'une fusion de l'ère Win10 de l'API entre Windows Phone et le bureau, permettant aux applications/bibliothèques du Windows Store d'être écrites pour les deux plates-formes . Ceci a été essentiellement remplacé par netstandard.
47
Stephen Cleary

Comme lié dans les commentaires, il y a déjà une description par Microsoft qui décrit toutes ces informations. Cependant, d'après votre réponse, il semble que vous n'ayez pas entièrement compris le tout. C'est très long, alors voici (espérons-le) une version tl; dr.

Nous commencerons par le tableau suivant à partir du lien ci-dessus, et j'espère que cela clarifiera une partie de la confusion:

.NET Standard compliance

Un bref aperçu pour les autres personnes qui trouveront cela plus tard: Les bibliothèques .NET ont parcouru un lot de changements et de ports au cours de ses 15 années d'existence. À cette époque, de nombreux smartphones sont maintenant presque aussi puissants que certains ordinateurs de bureau qui étaient utilisés en 2001. Dans cet intervalle, des sous-ensembles du framework .NET ont été créés (et rapidement abandonnés) pour une utilisation dans différents plates-formes. Avec la nouvelle approche de Satya Nadella pour rendre .NET aussi large que possible sur une plate-forme, les choses devaient changer.

Étant une technologie vieille de 15 ans, les choses devaient être améliorées. . NET Core est travaillé depuis 2014 comme une refonte complète de l'architecture .NET. Il a été réécrit à partir de zéro en tant que nouvelle version du langage .NET. L'un des objectifs de Core était de permettre le déploiement multiplateforme. Que ce soit une application à exécuter sur un iPhone/Android/XBox One, ou un site Web pouvant être hébergé dans IIS, ou sur une boîte Linux, .NET Core vous a couvert. Il le fait de plusieurs manières différentes, notamment en n'exigeant pas l'installation de .NET Framework sur la machine, et il emballera les bibliothèques nécessaires avec votre solution.

Plus particulièrement avec .NET Core, ce sont les changements radicaux apportés à ASP.NET. L'ancien System.Web est complètement disparu et réécrit pour être aussi performant que possible avec des résultats impressionnants . Les contrôleurs WebApi séparés ont disparu, car tout se fait dans un seul contrôleur. L'ensemble du processus est désormais opt-in par opposition à la valeur par défaut pour autoriser les choses que vous pourriez ne pas vouloir.

Cependant, en tant que développeurs, nous voudrons éventuellement migrer certaines applications, alors comment pouvons-nous être sûrs que le code que nous avons déjà écrit n'a pas eu plusieurs petits changements de nom mineurs dans les méthodes, interrompant ainsi la compilation de solutions géantes? En vient le . NET Standard . Il s'agit d'un ensemble d'API qui doivent être implémentées pour que votre plate-forme s'appelle ".NET".

Étant donné que le cadre NET de base avec lequel nous travaillons depuis des années est bien établi, il a servi de base à ce que la norme englobera. Cependant, tout n'est pas inclus, à quoi bon? Ainsi, la norme n'est que les API communes qui existeront entre les différents types de plates-formes .NET. Vous n'écrirez finalement pas de code dans ".NET Standard".

Xamarin (inclus dans le tableau ci-dessus) était acheté par Microsoft en 2016, et cette technologie a été utilisée pour aider à construire (ou du moins à inspirer) .NET Core pour être multiplateforme. Il existe toujours en tant qu'outil, mais dans la même veine que par le passé. Selon le tableau, il sera compatible .NET Standard 2.0 dans la version vNext. Cependant, son public cible ne changera pas.

Pour répondre directement à votre question, si vous souhaitez écrire une application avec la solution de déploiement unique la plus large possible, vous voudrez utiliser . NET Core . Cependant, si vous utilisez une bibliothèque qui est actuellement construite sur .NET Framework 2.0 et 4.5, alors vous serez bloqué en utilisant . NET Framework et en ayant cela séparément [~ # ~] uwp [~ # ~] solution pour cette cible.

S'il fournit quelque chose que vous pouvez appeler via un appel d'API Web, vous pouvez l'exécuter sur votre serveur dans .NET Framework et avoir une solution unique dans .NET Core à déployer auprès de vos utilisateurs finaux. S'il est intégré à votre code, vous n'avez malheureusement pas de chance jusqu'à ce qu'une mise à jour .NET Core soit fournie.

J'espère que cela a dissipé une partie de la confusion entre les différents noms de technologie.

[~ # ~] modifier [~ # ~]

Après quelques éclaircissements sur votre situation particulière, je peux clarifier les choses pour vous. Vous ne pouvez pas créer une solution unique qui ciblera à la fois .NET Framework et .NET Core. La compilation s'effectue de manières complètement différentes, avec des technologies sous-jacentes différentes. Il s'agit donc de la même situation que d'essayer d'utiliser votre version .NET 4.5 dans une solution .NET 2.0.

Cependant, il existe tutoriels pour vous permettre de porter votre projet sur Core. Pour la plupart, copiez simplement les corps de classe dans votre solution .NET Core et la plupart des choses fonctionneront correctement. Il y a des morceaux qui ont été abandonnés, certains qui n'ont pas encore été complètement étoffés à 100% (pas pour votre cas, mais Entity Framework n'a pas toutes les mêmes fonctionnalités par exemple). Il y a aussi des appels qui ont un peu changé.

La bonne nouvelle est que, pour aller de l'avant, .NET Core vous donnera la portée la plus large possible. .NET Framework ne va pas disparaître, mais Core et Core seront beaucoup plus synchronisés les uns avec les autres.

L'autre avantage de .NET Core est qu'il utilise une approche itérative du déploiement afin que vous n'attendiez pas 2 ans pour la prochaine mise à niveau majeure. Avec tout ce qui est livré via NuGet, vous aurez un délai d'exécution beaucoup plus rapide sur les améliorations et les nouvelles fonctionnalités.

22
krillgar

Je suppose que vous avez déjà lu l'article Microsoft avec le tableau Nice et que tout est clair comme de la boue maintenant. Si c'est le cas, vous êtes dans le même bateau que moi avant de passer la majeure partie de l'après-midi à étudier cela (et à essayer de porter ma bibliothèque riche en réflexions sur .NET Core, que je devrais mentionner est aussi ma uniquement effort de portage .NET Core). Ce qui suit n'est pas la ligne officielle du parti, mais mon résumé personnel de ce que j'ai trouvé à travers de nombreuses lectures (et en tant que développeur .NET depuis .NET 1.0). Je ne peux pas garantir sa précision totale (surtout en ce qui concerne le développement mobile, dont je suis presque entièrement ignorant) et les corrections sont certainement les bienvenues. S'il y en a beaucoup, je vais juste en faire un wiki.

Je vais le parcourir plus ou moins chronologiquement parce que j'ai trouvé que cela avait le plus de sens si vous voulez comprendre comment l'ancien et le nouveau sont liés. Cela devrait probablement être beaucoup réduit, mais à l'heure actuelle, je n'ai pas le temps de le faire. Il y a cependant une version TL; DR à la toute fin.

La route longue et sinueuse

Malgré son Java, .NET n'a jamais sérieusement tenté d'être "écrit une fois, exécuté n'importe où". Il a commencé tout autant dans le camp de Windows, et même s'il compile en bytecode et n'est pas allé trop loin avec des Windowsismes explicites et est donc théoriquement très portable, ce n'est pas ce qui intéressait vraiment MS. Une partie du .NET Framework était open source dès le début, et un tas des passionnés de l'open source l'ont récupéré et ont couru avec, nous donnant Mono . Mono est important car c'est la première plateforme alternative et ensemble de bibliothèques pour .NET et illustre les idées de plate-forme versus bibliothèque versus toolchain. Mono tente de donner une implémentation (plus ou moins) complète du Common Language Le Runtime et sa bibliothèque de classes de base associée. C'est important: bien que Mono fonctionne sous Linux (et certains autres Unices), ce n'est pas pas une plateforme distincte dans la mesure où il implémente (certaines versions de) le CLR + BCL. Il y a runt les différences imes (noms de chemins et similaires) qui importent aux développeurs d'applications, mais pour la programmation pratique des bibliothèques, vous pouvez considérer Mono et le .NET Framework pour Windows "la même" plate-forme avec une implémentation légèrement différente. J'insiste sur ce point car nous allons rencontrer du code .NET ciblant Windows qui ne fonctionne pas sur le CLR et qui est (ironiquement ou autrement) plus difficile à porter.

Puis est venu Windows Phone (plusieurs versions), Windows CE (plusieurs versions), Windows Embedded CE, Windows Toaster (OK, celui-ci n'existe pas vraiment) et une saveur de .NET a été fondamentalement réinventée à chaque fois - toujours .NET mais avec des éléments fondamentaux de l'exécution et/ou BCL manquants ou modifiés. Voici où nous obtenons . NET Compact , . NET Micro , Windows Phone (ancien style, pas de nom séparé pour le framework) et Silverlight . Tous ces éléments doivent être considérés comme des combinaisons de plates-formes + bibliothèques distinctes qui ressemblent suffisamment au .NET Framework pour rendre possible le développement multiplateforme, mais qui en diffèrent suffisamment pour que ne soit pas aussi simple . Comme garder une trace de ce qui était pris en charge était devenu le plus gênant pour les bibliothèques partagées, quelqu'un a eu l'idée de bibliothèques de classes portables et de leurs profils associés (la collection dont est connu sous le nom de . NET Portable Reference Assemblies ).

Fondamentalement, vous ciblez un ensemble de combinaisons spécifiques de version .NET, de plate-forme (et de bibliothèque), et vous obtenez des assemblys de référence qui imitent ces combinaisons pour compiler. De nombreux profils différents existent selon les saveurs que vous souhaitez explicitement cibler. Ce fut une première tentative de ce que .NET Standard essaie maintenant à plus grande échelle. Fondamentalement, PCL est désormais obsolète, sauf si vous ciblez quelque chose .NET Standard n'essaie pas de prendre en charge . .NET Standard supprime l'idée d'un milliard de profils différents, ce qui est bien, au détriment de la suppression de certaines choses que votre bibliothèque pourrait cibler plus tôt, ce qui est mauvais. Il existe des ressources en ligne pour faciliter la transition de PCL à .NET Standard. Si vous regardez du code portable maintenant , vous ne voulez pas vous concentrer sur PCL, sauf si vous voulez vraiment prendre en charge certaines plates-formes assez marginales (aucune infraction destinée aux personnes qui continuent de développer pour leur).

La plateforme Windows universelle est, comme son nom l'indique, une plateforme. Plus précisément, c'est la plate-forme .NET qui est prise en charge par les applications du Windows Store (à la fois sur le bureau et sur le téléphone). Voilà, ni plus, ni moins. Il est préférable de le considérer comme le successeur naturel de Silverlight en ce sens qu'il s'agit d'un support de cadre en bac à sable pour les ordinateurs de bureau et les mobiles. Malgré son nom, ce n'est pas une plate-forme universelle et ce n'est pas ce que vous voulez que tout votre code cible. C'est une plate-forme que vous voudrez peut-être activer pour votre code, et elle est unique en ce sens que c'est la seule plate-forme que je connaisse qui a deux temps d'exécution dans la même version. À venir!

. NET Native n'était pas mentionné dans le message d'origine mais revient souvent dans ces discussions car il est également nouveau, comme .NET Core, et sonne très sexy car il compile .NET directement en code machine (compilation d'avance, pas de compilation JIT). Ce n'est pas une nouvelle plate-forme complète mais un nouveau runtime pour les applications UWP (et seulement celles-ci) lorsqu'elles sont compilées en mode Release. En mode débogage, ils utilisent le CoreCLR (le runtime .NET Core). Vous n'aurez pas besoin d'y penser très dur, sauf si vous voulez vraiment créer une application UWP, car il y a toutes sortes de choses intéressantes en cours avec la réflexion dans .NET Native qui nécessitent une attention distincte du développeur de l'application.

Et maintenant, nous arrivons à . NET Core ! .NET Core a commencé comme "ASP.NET Core", mais les gens se sont vite rendu compte qu'il pourrait être beaucoup plus gros que cela. .NET Core est un nouveau combo runtime (CoreCLR) + bibliothèque avec prise en charge multiplateforme explicite (comme dans cross-OS). Contrairement au combo CLR + BCL, où il existe une version Windows et une version Unix sous la forme Mono, .NET Core est une base de code pour toutes les plates-formes (avec les bits croquants spécifiques à la plate-forme habituels pour prendre en charge la couche portable moelleuse ci-dessus, bien sûr) . Ce qui déroute davantage les gens, c'est que .NET Core est également le nom d'un nouveau type de chaîne d'outils/projet pour prendre en charge la création d'applications .NET Core, alors qu'avant nous n'avions que MSBuild. Cela a été rendu nécessaire par l'absence de Visual Studio pour Linux, mais MS est s'éloigne déjà de cette approche "gardons les choses simples et JSON" et revient à un format universel pour .NET Framework et. NET Core (et ça va être MSBuild, car il y a beaucoup plus de repos là-dessus).

.NET Core est pour la plupart très compatible avec le .NET Framework. Par conséquent, si votre application .NET Core s'exécute réellement sur le .NET Framework (sous Windows), elle peut charger des assemblys qui ciblent le .NET Framework, et pas simplement .NET Core. Ceci est une source importante de confusion et de code non transférable: alors que vous pouvez construire et charger ces assemblys, ils rendront votre code non portable. .NET Core lui-même ne vous empêchera pas de le faire; .NET Standard (à venir), si vous alignez correctement vos déclarations.

Jusqu'à présent avec moi? Bien, car maintenant nous sommes prêts à laisser tomber . NET Standard sur votre tête sans méfiance. .NET Standard n'est pas une plate-forme (dans le sens où vous ne pouvez pas le télécharger et l'installer sur une machine), ce n'est pas une bibliothèque (mais il existe des packages pour la prendre en charge à des fins de génération), c'est un profil. C'est une tentative de normaliser la surface de la bibliothèque sur un large éventail de choses que nous venons de discuter. L'idée étant que si votre code cible .NET Standard XY, il vous suffit de basculer vos outils de génération sur "s'il vous plaît, donnez-moi .NET Standard XY" et lorsque vous créez votre assembly, vous pouvez être sûr il sera utilisable pour toutes les plateformes couvertes par XY Hourra! Le monde est à nouveau simple!

Eh bien, ce n'est pas encore le cas. Le problème est que .NET Core est actuellement en développement lourd, ce qui signifie que beaucoup de choses sont manquantes ou différentes - même des choses assez fondamentales qui peuvent être naturellement présentes dans votre base de code .NET Framework, comme marquer vos exceptions Serializable et en leur donnant un constructeur séparé pour la désérialisation afin qu'ils fonctionnent bien sur AppDomains. Il n'y a pas de AppDomain dans .NET Core, donc pas de sérialisation, donc ces constructeurs ne compileront pas. Même l'attribut Serializable lui-même est manquant dans les anciennes versions de CoreCLR. Si votre projet MSBuild utilise des cibles personnalisées, tant pis, la chaîne d'outils .NET Core ne prend pas en charge ces éléments pour le moment (il se peut, à l'avenir, que ce soit à nouveau MSBuild). Vous pouvez réécrire, bien sûr, mais pas réutiliser. Ainsi, bien que vous puissiez cibler .NET Standard, vous devrez peut-être deux projets distincts et/ou une compilation conditionnelle pour obtenir votre assemblage .NET Standard pour deux plates-formes différentes. Si vous avez de la chance (ou pouvez compromettre un peu), votre bibliothèque est suffisamment simple pour que la construire avec .NET Core seul puisse suffire. Ne vous y trompez pas: il existe encore plusieurs plates-formes .NET et elles ont toujours leurs différences, .NET Standard essaie simplement de rendre plus facile le portage. Jusqu'à présent, il est limité, mais fait déjà un travail plus propre que PCL.

Pour résumer un peu: .NET Core et .NET Framework (et tous leurs petits cousins ​​et neveux) sont des plates-formes distinctes à la fois conceptuellement et par implémentation. .NET Standard est un profil de ciblage qui simplifie les efforts nécessaires pour porter le code entre eux (mais ne le rend pas encore complètement transparent). PCL est le précurseur de la norme qui peut être ignoré si vous êtes progressif.


TL; DR commence ici (mais est toujours TL)

Pour enfin répondre à votre question, que devez-vous faire si vous êtes un développeur de bibliothèque moderne et que vous souhaitez cibler "un public aussi large que possible"? Eh bien tout d'abord, vous devez le réduire si possible. Sur quelles plateformes allez-vous explicitement prendre en charge et tester? Voulez-vous vraiment cibler .NET Compact sur votre XBox 360? Windows Phone 7? Le Silverlight d'il y a huit ans? Si vous le faites, vous ne pourrez probablement pas contourner le PCL, mais la plupart d'entre nous auront le luxe de pouvoir éviter cela. Sinon: mettez en file d'attente une génération PCL distincte si votre profil ne correspond à rien dans la norme .NET.

Votre bibliothèque est-elle très simple (sans réflexion, sans async/await, pas de dépendances sur des frameworks plus grands comme WCF)? Ensuite, vous pourrez peut-être cibler la section transversale de .NET 2.0 et la version la plus basse de .NET Standard qui possède les dépendances de structure dont vous avez besoin. Ne vous laissez pas berner, les versions inférieures de .NET Standard sont vraiment limitées de manière décevante dans ce qu'elles offrent, mais vous devez payer un certain prix pour la portabilité. Il n'y a pas de prise en charge de la chaîne d'outils pour la construction de .NET 2.0 et de certaines versions de .NET Standard. Vous devez le construire deux fois et le tester "partout", bien que la section transversale signifie que vous pouvez être raisonnablement sûr qu'il fonctionnera s'il compile. La bibliothèque résultante prendra en charge chaque plate-forme .NET unique qui peut charger des assemblages Vanilla .NET 2.0 (qui sont presque tous, mais notamment pas Micro et Compact) et .NET Core, et tous sans basculement de plate-forme. Félicitations, le monde n'a jamais vu quelque chose d'aussi portable!

Votre bibliothèque utilisera-t-elle la réflexion? Ensuite, vous ne pouvez probablement pas contourner la réécriture du code pour le compiler pour .NET Core, car l'API de réflexion a changé il y a quelque temps et votre code n'a peut-être pas encore rattrapé (car il n'y avait pas besoin si vous avez continué à cibler le cadre complet uniquement). Dans ce cas, vous souhaiterez faire passer votre version de .NET Framework ciblée à 4.5, car il s'agit de la version de .NET Framework compatible avec ces modifications. Ici, vous commencez à prendre en charge les outils: vous pouvez cibler .NET Standard 1.1, qui couvre un sous-ensemble de .NET 4.5. Si vous trouvez que ce sous-ensemble n'est pas suffisant, vous devrez à nouveau recourir à la construction deux fois: pour le .NET Framework complet et pour .NET Core. La raison étant que .NET Core 1.0 prend en charge "plus" que .NET Framework 4.5, mais il n'y a pas encore de version du .NET Framework que vous pouvez cibler qui soit comparable à Core (qui sera "vNext"). Donc, si vous ne voulez pas vous limiter uniquement à .NET Core mais que vous souhaitez également prendre en charge ceux d'entre nous qui continuent de créer de simples applications de bureau 4.5 et .NET Standard 1.1 n'est pas assez pour vous, vous devrez vous séparer. La mauvaise chose à faire est de cibler 1.1 puis d'importer uniquement des packages/assemblys Framework 4.5, car cela vous procurera le pire des deux mondes en termes de portabilité!

Votre bibliothèque aura-t-elle besoin de certaines des améliorations/extensions par rapport à 4.5 qui ont été introduites dans 4.5.1 ou version ultérieure, ou des packages qui ne sont disponibles que pour les versions supérieures de .NET Standard? Cibler ensuite la version appropriée .NET Standard supérieure à la place. Notez que Microsoft ne prend plus officiellement en charge les versions 4.x inférieures à 4.5.2 . Cela ne signifie pas que vous ne devriez pas cibler ces versions (descendez aussi bas que vous pouvez raisonnablement), mais cela signifie que vous avez un argument pour utiliser rien de moins que .NET Standard 1.2, et si vous pouvez demander 4.6, pas moins de 1.5. Ce n'est pas un fardeau pour les consommateurs (si vous êtes disposé et capable d'installer 4.6, vous êtes presque certainement disposé et capable d'installer 4.6.2) et vous facilite la vie. En fonction de votre code, vous pouvez vous en tirer avec une build .NET Core uniquement, mais vous ne le voulez probablement pas, car la chaîne de build .NET Core n'est pas encore stable et reviendra à MSBuild (comme mentionné précédemment). Inutile de laisser tomber tous vos fichiers de projet pour JSON pour revenir en arrière plus tard!

Votre bibliothèque utilise-t-elle une sorte de compilation conditionnelle? Attention, avec la chaîne d'outils .NET Core, vous obtenez différents symboles prédéfinis . Ils sont extrêmement super ennuyeux car ils insistent pour (disons) faire une distinction entre 4.5, 4.5.1 et 4.5.2, ce qui est pénible si vous voulez couvrir "4.5 et au-delà". Rien qu'une construction soignée ne peut gérer, mais néanmoins quelque chose que vous devez prendre en compte.

Je ne couvre pas les versions mobiles ici (Xamarin et les anciennes versions de téléphone) parce que, bien, j'en sais très peu sur celles-ci! J'imagine que l'histoire est à peu près la même que la construction pour .NET Core et .NET Framework, dans la mesure où cette construction ne fonctionne qu'une fois pour les bibliothèques simples et les bibliothèques où vous n'avez pas à vous soucier de la compatibilité descendante et des besoins (au moins) deux versions sinon, mais comme je l'ai dit au début, les corrections sont les bienvenues.

20
Jeroen Mostert