Question

Cela me demande vraiment, alors j'espère que quelqu'un pourra me donner une justification raisonnable de la raison pour laquelle les choses sont comme elles sont.

NotImplementedException. Vous me tirez la jambe, n'est-ce pas?

Non, je ne vais pas m'attaquer à cela en disant, "accrochez-vous, la méthode est mise en œuvre - elle lève une exception NotImplementedException". Oui, c'est vrai, vous devez implémenter la méthode pour générer une exception NotImplementedException (contrairement à un appel de fonction virtuelle pure en C ++ - c'est logique!). Même si c'est sacrément drôle, il y a un problème plus grave dans mon esprit.

Je me demande simplement, en présence de NotImplementedException, comment peut-on faire quelque chose avec .Net? Vous attendez-vous à ce que chaque appel de méthode abstraite soit enveloppé d'un bloc catch try pour se protéger des méthodes qui pourraient ne pas être implémentées? Si vous attrapez une telle exception, qu'est-ce que vous êtes censé faire avec ça ??

Je ne vois aucun moyen de tester si une méthode est réellement implémentée sans l'appeler. Étant donné que l'appel peut avoir des effets secondaires, je ne peux pas effectuer toutes mes vérifications au préalable, puis exécuter mon algorithme. Je dois exécuter mon algorithme, intercepter NotImplementedExceptions et certains comment restaurer mon application dans un état sain.

C'est fou. Furieux. Insensé. La question est donc la suivante: Pourquoi l’exception NotImplementedException existe-t-elle ?

En tant que frappe préventive, je ne souhaite pas que quiconque réponde, "car les concepteurs doivent intégrer cela dans le code généré automatiquement." C'est horrible. Je préférerais que le code généré automatiquement ne soit pas compilé jusqu'à ce que vous fournissiez une implémentation. Par exemple, l'implémentation générée automatiquement pourrait être "jeter la NotImplementedException"; où l'exception NotImplementedException n'est pas définie!

Quelqu'un a-t-il déjà attrapé et manipulé une exception NotImplementedException? Avez-vous déjà laissé une exception NotImplementedException dans votre code? Si tel est le cas, cela représente-t-il une bombe à retardement (c’est-à-dire que vous l’avez laissée par accident) ou un défaut de conception (la méthode ne doit pas être mise en œuvre et ne sera jamais appelée)?

Je suis également très méfiant vis-à-vis de l'exception NotSupportedException ... Non supporté? Qu'est-ce que Si ce n'est pas supporté, pourquoi fait-il partie de votre interface? Quelqu'un chez Microsoft peut-il épeler un héritage inapproprié? Mais je pourrais poser une autre question à ce sujet si je ne suis pas trop maltraité pour celui-ci.

Informations supplémentaires:

Ceci est une lecture intéressante sur le sujet.

Il semble y avoir un fort accord avec Brad Abrams que "NotImplementedException" concerne des fonctionnalités qui ne sont pas encore implémentées, mais qui devraient (et le seront). Quelque chose comme ce que vous pourriez commencer lorsque vous construisez une classe, obtenez toutes les méthodes en lançant NotImplementedException, puis éliminez-les avec du code réel… "

Commentaires de Jared Parsons sont très faibles et doivent probablement être ignorés: NotImplementedException: lève cette exception lorsqu'un type n'implémente une méthode pour aucune autre raison.

Le MSDN est encore plus faible en la matière. indiquant que "l'exception qui est levée lorsqu'une méthode ou une opération demandée n'est pas implémentée".

Était-ce utile?

La solution

Il y a une situation qui me semble utile: le TDD.

J'écris mes tests, puis je crée des stubs pour que les tests soient compilés. Ces bouts ne font rien d'autre que lancer une nouvelle NotImplementedException (); . De cette façon, les tests échoueront par défaut, peu importe quoi. Si j'utilisais une valeur de retour fictive, cela pourrait générer des faux positifs. Maintenant que tous les tests se compilent et échouent car il n’ya pas d’implémentation, j’aborde ces bouts.

Etant donné que je n'utilise jamais une NotImplementedException dans aucune autre situation, aucune NotImplementedException ne passera jamais dans le code de version, car certains tests échoueront toujours.

Vous n'avez pas besoin de tout comprendre. De bonnes API documentent les exceptions levées. Ce sont ceux que vous devriez rechercher.

EDIT: j'ai écrit une règle FxCop pour les trouver.

Ceci est le code:

using System;
using Microsoft.FxCop.Sdk;

/// <summary>
/// An FxCop rule to ensure no <see cref="NotImplementedException"/> is
/// left behind on production code.
/// </summary>
internal class DoNotRaiseNotImplementedException : BaseIntrospectionRule
{
    private TypeNode _notImplementedException;
    private Member _currentMember;

    public DoNotRaiseNotImplementedException()
        : base("DoNotRaiseNotImplementedException",
               // The following string must be the assembly name (here
               // Bevonn.CodeAnalysis) followed by a dot and then the
               // metadata file name without the xml extension (here
               // DesignRules). See the note at the end for more details.
               "Bevonn.CodeAnalysis.DesignRules",
               typeof (DoNotRaiseNotImplementedException).Assembly) { }

    public override void BeforeAnalysis()
    {
        base.BeforeAnalysis();
        _notImplementedException = FrameworkAssemblies.Mscorlib.GetType(
            Identifier.For("System"),
            Identifier.For("NotImplementedException"));
    }

    public override ProblemCollection Check(Member member)
    {
        var method = member as Method;
        if (method != null)
        {
            _currentMember = member;
            VisitStatements(method.Body.Statements);
        }
        return Problems;
    }

    public override void VisitThrow(ThrowNode throwInstruction)
    {
        if (throwInstruction.Expression != null &&
            throwInstruction.Expression.Type.IsAssignableTo(_notImplementedException))
        {
            var problem = new Problem(
                GetResolution(),
                throwInstruction.SourceContext,
                _currentMember.Name.Name);
            Problems.Add(problem);
        }
    }
}

Et voici les métadonnées de la règle:

<?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="Bevonn Design Rules">
  <Rule TypeName="DoNotRaiseNotImplementedException" Category="Bevonn.Design" CheckId="BCA0001">
    <Name>Do not raise NotImplementedException</Name>
    <Description>NotImplementedException should not be used in production code.</Description>
    <Url>http://stackoverflow.com/questions/410719/notimplementedexception-are-they-kidding-me</Url>
    <Resolution>Implement the method or property accessor.</Resolution>
    <MessageLevel Certainty="100">CriticalError</MessageLevel>
    <Email></Email>
    <FixCategories>NonBreaking</FixCategories>
    <Owner></Owner>
  </Rule>
</Rules>

Pour construire ceci, vous devez:

  • référence Microsoft.FxCop.Sdk.dll et Microsoft.Cci.dll

  • Placez les métadonnées dans un fichier nommé DesignRules.xml et ajoutez-le en tant que ressource incorporée à votre assemblage

  • Nommez votre assembly Bevonn.CodeAnalysis . Si vous souhaitez utiliser des noms différents pour les métadonnées ou les fichiers d'assemblage, veillez à modifier le second paramètre en conséquence pour le constructeur de base.

Ajoutez simplement l'assemblage obtenu à vos règles FxCop et supprimez ces maudites exceptions de votre précieux code. Il existe des cas où aucune exception NotImplementedException ne sera signalée, mais je pense vraiment que vous êtes sans espoir si vous écrivez un tel code cthulhian. Pour des utilisations normales, c’est-à-dire que lance la nouvelle NotImplementedException (); , cela fonctionne et c’est tout ce qui compte.

Autres conseils

Il est là pour prendre en charge un cas d'utilisation assez courant, une API fonctionnelle mais partiellement complétée. Dites que je veux que les développeurs testent et évaluent mon API - WashDishes () fonctionne, au moins sur ma machine, mais je n’ai pas encore réussi à coder DryDishes () , encore moins PutAwayDishes () . Plutôt que d’échouer en silence ou de donner un message d’erreur cryptique, je peux expliquer très bien pourquoi DryDishes () ne fonctionne pas - je ne l’ai pas encore implémenté.

Son exception soeur NotSupportedException est particulièrement utile pour les modèles de fournisseur. Beaucoup de lave-vaisselle ont une fonction de séchage, donc appartient à l'interface, mais mon lave-vaisselle pas cher ne le supporte pas. Je peux le faire savoir via NotSupportedException

Je vais résumer mon point de vue à ce sujet au même endroit, car ils sont dispersés dans quelques commentaires:

  1. Vous utilisez NotImplementedException pour indiquer qu'un membre d'interface n'est pas encore implémenté, mais le sera. Vous combinez cela avec des tests unitaires automatisés ou des tests d'assurance qualité pour identifier les fonctionnalités qui doivent encore être implémentées.

  2. Une fois la fonctionnalité implémentée, vous supprimez la NotImplementedException . De nouveaux tests unitaires sont écrits pour la fonctionnalité afin de s’assurer de son bon fonctionnement.

  3. NotSupportedException est généralement utilisé pour les fournisseurs qui ne prennent pas en charge les fonctionnalités qui n'ont pas de sens pour des types spécifiques. Dans ces cas, les types spécifiques lèvent l'exception, les clients les interceptent et les traitent comme il convient.

  4. La raison pour laquelle NotImplementedException et NotSupportedException existe dans le Framework est simple: les situations qui les mènent sont communes, il est donc logique de les définir. dans le Framework, afin que les développeurs ne soient pas obligés de les redéfinir. En outre, il est facile pour les clients de savoir quelle exception capturer (en particulier dans le contexte d’un test unitaire). Si vous devez définir votre propre exception, ils doivent déterminer quelle exception capturer, ce qui est à tout le moins une perte de temps contre-productive et qui est souvent incorrecte.

  

Pourquoi l'exception NotImplementedException   existe?

NotImplementedException est un excellent moyen de dire que quelque chose n'est pas encore prêt. Pourquoi ce n'est pas prêt est une question distincte pour les auteurs de la méthode. Dans le code de production, il est peu probable que vous rencontriez cette exception, mais si vous y parvenez, vous pouvez immédiatement voir ce qui s'est passé et il est bien mieux d'essayer de comprendre pourquoi les méthodes ont été appelées, mais rien ne s'est passé ou pire encore: recevoir des messages "temporaires". résultat et obtenir " funny " effets secondaires.

  

NotImplementedException est-il le C #   équivalent de Java   UnsupportedOperationException?

Non, .NET a une exception NotSupportedException

  

Je dois exécuter mon algorithme, attraper   NotImplementedExceptions et les uns   comment faire reculer mon application à certains   état sain

Une bonne API possède une documentation sur les méthodes XML qui décrit les exceptions possibles.

  

Je suis très méfiant du   NotSupportedException aussi ... Not   prise en charge? Qu'est-ce que Si ce n'est pas   pris en charge, pourquoi fait-il partie de votre   interface?

Il peut y avoir des millions de raisons. Par exemple, vous pouvez introduire une nouvelle version de l'API sans toutefois prendre en charge les anciennes méthodes. Là encore, il est bien préférable de voir une exception descriptive plutôt que de creuser dans la documentation ou de déboguer du code tiers.

L'utilisation d'une exception NotImplementedException est principalement utilisée dans le code de raccord généré: vous n'oublierez donc pas de l'implémenter !! Par exemple, Visual Studio implémentera explicitement les méthodes / propriétés d'une interface avec le corps lançant une exception NotImplementedException.

Re NotImplementedException - cela sert à quelques utilisations; il fournit une seule exception que (par exemple) vos tests unitaires peuvent se verrouiller pour un travail incomplet. Mais aussi, il fait vraiment ce qui est dit: ce n’est tout simplement pas là. Par exemple, " mono " jette cela partout pour les méthodes qui existent dans les bibliothèques MS, mais qui n’ont pas encore été écrites.

Re NotSupportedException - tout n'est pas disponible. Par exemple, de nombreuses interfaces prennent en charge une paire "pouvez-vous le faire?" / "faire ceci". Si le "pouvez-vous faire cela?" renvoie false, il est parfaitement raisonnable de procéder de la manière suivante: "Faites ceci". lancer NotSupportedException . Des exemples pourraient être IBindingList.SupportsSearching / IBindingList.Find () etc.

La plupart des développeurs Microsoft connaissent bien les modèles de conception dans lesquels une exception NotImplementedException est appropriée. C'est assez courant en fait.

Un modèle composite , où de nombreux objets peuvent être traités comme un seul exemple, en est un bon exemple. instance d'un objet. Un composant est utilisé comme classe abstraite de base pour les classes feuille héritées (correctement). Par exemple, une classe File and Directory peut hériter de la même classe de base abstraite, car il s'agit de types très similaires. De cette façon, ils peuvent être traités comme un seul objet (ce qui est logique lorsque vous réfléchissez à ce que sont les fichiers et les répertoires - sous Unix par exemple, tout est un fichier).

Donc, dans cet exemple, il y aurait une méthode GetFiles () pour la classe Directory, mais la classe File n'implémenterait pas cette méthode, car cela n'a aucun sens de le faire. Au lieu de cela, vous obtenez une exception NotImplementedException, car un fichier n’a pas d’enfants comme un annuaire.

Notez que cela ne se limite pas à .NET - vous trouverez ce modèle dans de nombreux langages et plates-formes OO.

Pourquoi ressentez-vous le besoin de saisir toutes les exceptions possibles? Enveloppez-vous chaque appel de méthode avec catch (NullReferenceException ex) aussi?

Le code de remplacement renvoyant NotImplementedException est un espace réservé. S'il parvient à être publié, il devrait contenir un bogue, tout comme NullReferenceException .

Je pense qu'il existe de nombreuses raisons pour lesquelles MS a ajouté NotImplementedException au framework:

  • À titre de commodité; comme beaucoup de développeurs en auront besoin pendant le développement, pourquoi tout le monde devrait-il rouler le son?
  • Pour que les outils puissent compter sur sa présence. Par exemple, l'option "Implement Interface" de Visual Studio. La commande génère des stubs de méthode qui lancent NotImplementedException. Si ce n’était pas le cadre, cela ne serait pas possible, ou du moins plutôt gênant (par exemple, cela pourrait générer du code qui ne serait pas compilé tant que vous n’auriez pas ajouté votre propre exception NotImplementedException)
  • Encourager une "pratique standard" cohérente

Frankodwyer pense que NotImplementedException est une bombe à retardement potentielle. Je dirais que tout code non fini est une bombe à retardement, mais NotImplementedException est beaucoup plus facile à désarmer que les alternatives. Par exemple, vous pouvez demander à votre serveur de génération d'analyser le code source pour toutes les utilisations de cette classe et de les signaler comme des avertissements. Si vous voulez vraiment le bannir, vous pouvez même ajouter un crochet de pré-validation à votre système de contrôle de code source pour empêcher l’archivage de ce code.

Bien sûr, si vous lancez votre propre exception NotImplementedException, vous pouvez la supprimer de la version finale pour vous assurer qu’il ne reste aucune bombe à retardement. Mais cela ne fonctionnera que si vous utilisez votre propre implémentation de manière cohérente dans toute l’équipe et vous devez vous assurer de ne pas oublier de la supprimer avant de la publier. En outre, vous constaterez peut-être que vous ne pouvez pas l'enlever. il existe peut-être quelques utilisations acceptables, par exemple dans le code de test qui n’est pas envoyé aux clients.

Il n'y a vraiment aucune raison de réellement attraper une exception NotImplementedException. Lorsque touché, il devrait tuer votre application, et le faire très douloureusement. Le seul moyen de résoudre ce problème ne consiste pas à le récupérer, mais à modifier votre code source (en implémentant la méthode appelée ou en modifiant le code appelant).

Deux raisons:

  1. Les méthodes sont réduites au cours du développement et lèvent une exception pour rappeler aux développeurs que l'écriture de leur code n'est pas terminée.

  2. Implémentation d'une interface de sous-classe qui, de par sa conception, n'implémente pas une ou plusieurs méthodes de la classe ou de l'interface de base héritée. (Certaines interfaces sont trop générales.)

Cela ressemble à un champ de mines potentiel pour moi. Dans le passé lointain, j'ai déjà travaillé sur un système de réseau existant qui fonctionnait sans interruption depuis des années et qui tombait en une journée. Lorsque nous avons suivi le problème, nous avons trouvé du code qui n’était manifestement pas terminé et qui n’aurait jamais pu fonctionner - littéralement, comme si le programmeur s’était interrompu pendant le codage. Il était évident que ce chemin de code particulier n'avait jamais été emprunté auparavant.

La loi de Murphy stipule que quelque chose de similaire ne fait que commencer dans le cas de NotImplementedException. Accordé en ces jours de TDD, etc., il devrait être récupéré avant la publication, et au moins vous pouvez grep le code pour cette exception avant la publication, mais quand même.

Lors des tests, il est difficile de garantir la couverture de chaque cas. Cela semble compliquer la tâche de votre travail en rendant plus difficiles les problèmes de temps de compilation. (Je pense qu'un type similaire de "dette technique" vient avec des systèmes qui reposent beaucoup sur le "typage de canards", alors que je reconnais qu'ils sont très utiles).

Vous avez besoin de cette exception pour COM Interop. C'est E_NOTIMPL . Le blog lié indique également d'autres raisons

Lancer NotImplementedException est le moyen le plus logique pour l'EDI de générer du code de remplacement compilé. Comme lorsque vous étendez l'interface et que Visual Studio la remplace pour vous.

Si vous avez utilisé un peu de C ++ / COM, cela existait également, à l'exception du nom E_NOTIMPL .

Il existe un cas d'utilisation valide pour cela. Si vous travaillez sur une méthode particulière d'une interface, vous voulez que votre code soit compilé afin que vous puissiez le déboguer et le tester. Selon votre logique, vous devrez supprimer la méthode de l'interface et mettre en commentaire le code de stub non compilant. C'est une approche très fondamentaliste et même si elle a du mérite, tout le monde ne va pas ou ne devrait pas adhérer à cela. En outre, vous souhaitez généralement que l'interface soit complète.

Avoir une exception NotImplementedException identifie bien les méthodes qui ne sont pas encore prêtes. En fin de journée, il suffit d’appuyer sur Ctrl + Maj + F pour toutes les trouver, je suis également sûr que le code statique les outils d’analyse le prendront aussi.

Vous n'êtes pas censé envoyer du code comportant une exception NotImplementedException . Si vous pensez qu'en ne l'utilisant pas, vous pourrez améliorer votre code, allez-y, mais vous pouvez améliorer la qualité de la source de manière plus productive.

NotImplementedException

L'exception est levée lorsqu'une méthode ou une opération demandée n'est pas implémentée.

En faisant de cela une exception unique définie dans le noyau .NET, il est plus facile de les trouver et de les éliminer. Si chaque développeur doit créer son propre ACME.EmaNymton.NotImplementedException , il sera plus difficile de tous les trouver.

Exception NotSupportedException

L'exception est levée lorsqu'une méthode invoquée n'est pas prise en charge.

Par exemple, en cas de tentative de lecture, de recherche ou d'écriture dans un flux ne prenant pas en charge la fonctionnalité invoquée.

Par exemple, les itérateurs générés (en utilisant le mot-clé yield ) est un IEnumerator , mais la méthode IEnumerator.Reset renvoie NotSupportedException .

A partir de ECMA-335, la spécification CLI, plus précisément les types de bibliothèque CLI, System.NotImplementedException, section remarques:

"Un certain nombre de types et de constructions, spécifiés ailleurs dans la présente norme, ne sont pas requis pour les implémentations CLI qui se conforment uniquement au profil de noyau. Par exemple, le jeu d'entités à virgule flottante est constitué des types de données à virgule flottante System.Single et System.Double. Si la prise en charge de ces éléments est omise dans une implémentation, toute tentative de référence à une signature incluant les types de données à virgule flottante entraîne une exception de type System.NotImplementedException. "

Ainsi, l'exception est destinée aux implémentations qui implémentent uniquement des profils de conformité minimaux. Le profil minimal requis est le profil du noyau (voir ECMA-335, 4e édition - Partition IV, section 3), qui inclut la BCL, raison pour laquelle l'exception est incluse dans "l'API principale" et non ailleurs.

Utiliser l'exception pour désigner les méthodes composées en stub, ou pour les méthodes générées par le concepteur manquant d'implémentation, est une mauvaise compréhension de l'intention de l'exception.

La raison pour laquelle ces informations ne sont PAS incluses dans la documentation MSDN pour la mise en œuvre de l'interface de ligne de commande par MS me dépasse.

Je ne peux pas me porter garant pour NotImplementedException (je suis principalement d'accord avec votre point de vue), mais j'ai largement utilisé NotSupportedException dans la bibliothèque principale utilisée au travail. DatabaseController, par exemple, vous permet de créer une base de données de tout type pris en charge, puis d'utiliser la classe DatabaseController dans le reste de votre code sans trop vous soucier du type de base de données sous-jacent. Assez basique, non? Où NotSupportedException est pratique (et où j'aurais utilisé ma propre implémentation si elle n'existait pas déjà), il y a deux instances principales:

1) Migration d'une application vers une autre base de données On dit souvent que cela se produit rarement, voire jamais, ou est nécessaire. Bullsh * t. Sortez plus.

2) Même base de données, pilote différent L'exemple le plus récent est celui d'un client utilisant une application basée sur Access mise à niveau de WinXP vers Win7 x64. N'étant pas un pilote JET 64 bits, leur informaticien a plutôt installé AccessDatabaseEngine. Lorsque notre application se bloquait, nous pouvions facilement voir dans le journal que DB.Connect se bloquait avec NotSupportedException - auquel nous avons rapidement pu remédier. Un autre exemple récent est l’un de nos programmeurs essayant d’utiliser des transactions sur une base de données Access. Même si Access prend en charge les transactions, notre bibliothèque ne prend pas en charge les transactions Access (pour des raisons ne relevant pas de cet article). NotSupportedException, c'est le moment de briller!

3) Fonctions génériques Je ne peux pas penser à un "expérience d'expérience" concis. exemple ici, mais si vous pensez à quelque chose comme une fonction qui ajoute une pièce jointe à un courrier électronique, vous voulez que celui-ci puisse prendre quelques fichiers communs comme les JPEG, tout ce qui est dérivé de différentes classes de flux et pratiquement tout ce qui a un ". ToString " méthode. Pour la dernière partie, vous ne pouvez certainement pas prendre en compte tous les types possibles, vous devez donc le rendre générique. Lorsqu'un utilisateur passe OurCrazyDataTypeForContainingProprietarySpreadsheetData, utilisez la réflexion pour tester la présence d'une méthode ToString et renvoyez NotSupportedException pour indiquer un manque de prise en charge desdits types de données qui ne prennent pas en charge ToString.

NotSupportedException n’est certes pas une fonctionnalité cruciale, mais c’est quelque chose que je me trouve de plus en plus utilisé alors que je travaille sur de plus grands projets.

Disons que vous avez cette méthode dans votre code de production

public void DoSomething()

Lequel prendriez-vous si vous voulez le laisser plus tard pour le terminer?

public void DoSomething()
{
}

ou

public void DoSomething()
{
    throw new NotImplementedException();
}

Je prendrais certainement la seconde. Couplé à Elmah ou à tout autre mécanisme de consignation des erreurs (implémenté comme un aspect de l’application entière). Avec le filtrage des journaux / exceptions pour déclencher la notification par courrier électronique d’erreur critique lorsqu’une erreur est détectée.

L'argument que NotImplementedException == inachevé n'est pas correct non plus. (1) La capture des méthodes non implémentées doit être laissée aux tests unitaires / tests d'intégration. Si vous avez une couverture de 100% (ce que vous devriez maintenant faire, avec autant d'outils de génération de simulacre / stub / code) sans exception NotImplementedException, quels sont vos soucis? (2) Génération de code. Simple simple. Encore une fois, si je génère le code et n’utilise que la moitié du code généré, pourquoi n’aurais-je pas NotImplementedException dans le reste du stub généré?

C'est comme dire que le code ne devrait pas être compilé à moins que chaque entrée nullable ne soit vérifiée / traitée pour null. (AKA l'erreur d'un billion de dollars, sinon plus). La langue doit être souple, tandis que les tests / contrats doivent être solides.

Je l’utilise rarement pour la correction d’interface. Supposons que vous ayez une interface à respecter, mais que cette méthode ne soit jamais appelée par quelqu'un. Il vous suffit donc de coller une exception NotImplementedException. Si quelqu'un l'appelle, il saura qu'il fait quelque chose de mal.

NotImplementedException est levée pour une méthode de .NET (voir l’analyseur C # dans Code DOM qui n’est pas implémenté, mais la méthode existe!) Vous pouvez vérifier avec cette méthode Microsoft.CSharp.CSharpCodeProvider.Parse

Ils sont tous les deux des hacks pour deux problèmes communs.

NotImplementedException est une solution de contournement pour les développeurs qui sont des astronautes de l’architecture et qui souhaitent écrire l’API d’abord, puis le code plus tard. Évidemment, comme il ne s’agit pas d’un processus incrémentiel, vous ne pouvez pas mettre en œuvre tout à la fois et vous voulez donc prétendre être à moitié fait en lançant NotImplementedException.

NotSupportedException est un hack sur la limitation des systèmes de types comme ceux trouvés dans C # et Java. Dans ces systèmes de types, vous dites qu'un rectangle est une forme si le rectangle hérite de toutes les caractéristiques de formes (y compris les fonctions membres et les variables). Cependant, dans la pratique, ce n'est pas vrai. Par exemple, un carré est un rectangle, mais un carré est une restriction d'un rectangle, pas une généralisation.

Ainsi, lorsque vous souhaitez hériter et restreindre le comportement de la classe parent, vous lancez NotSupported sur des méthodes qui n'ont pas de sens pour la restriction.

Qu'en est-il des prototypes ou des projets inachevés?

Je ne pense pas que ce soit une très mauvaise idée d'utiliser une exception (bien que j'utilise une boîte de message dans ce cas).

Eh bien, je suis un peu d'accord. Si une interface a été conçue de telle sorte que toutes les classes ne puissent pas en implémenter tous les éléments, elle aurait dû être décomposée à mon avis.

Si IList peut ou ne peut pas être modifié, il aurait dû être divisé en deux, un pour la partie non modifiable (accesseurs, recherche, etc.) et un pour la partie modifiable (paramètres, ajout, suppression, etc.). ).

J'ai quelques NotImplementedExceptions dans mon code. Souvent, cela provient d'une partie d'une interface ou d'une classe abstraite. Certaines méthodes dont j’aurai peut-être besoin à l’avenir ont du sens comme faisant partie de la classe, mais je ne veux pas prendre le temps de les ajouter, sauf si j’en ai réellement besoin. Par exemple, j'ai une interface pour tous les types de statistiques de mon jeu. Un de ces types est un ModStat, qui est la somme de la statistique de base plus tous les modificateurs (armes, armures, sorts). Mon interface statistique a un événement OnChanged, mais mon ModStat fonctionne en calculant la somme de toutes les statistiques auxquelles il fait référence à chaque appel. Donc, au lieu d’avoir la surcharge d’une tonne d’événements ModStat.OnChange levés chaque fois qu’une statistique est modifiée, une exception NotImplementedException est émise si quelqu'un essaie d’ajouter ou de supprimer un écouteur à OnChange.

Les langages .NET sont une question de productivité, alors pourquoi passer votre temps à coder quelque chose que vous n'utiliserez même pas?

Voici un exemple: en Java, chaque fois que vous implémentez l'interface Iterator , vous devez remplacer les méthodes évidentes hasNext () et next () , mais il existe aussi delete () . Dans 99% des cas d'utilisation que j'ai, je n'en ai pas besoin, alors je lance simplement une NotImplementedException . C’est bien mieux que de ne rien faire en silence.

L'exception NotImplementedException existe uniquement pour faciliter le développement. Imaginez que vous commencez à implémenter une interface. Vous voudriez pouvoir au moins construire lorsque vous avez fini d'implémenter une méthode, avant de passer à la suivante. Stubbing les méthodes NotImplemented avec NotImplementedExceptions est un excellent moyen de vivre un code non fini qui est super facile à repérer plus tard. Sinon, vous courriez le risque de mettre en œuvre rapidement quelque chose que vous pourriez oublier de réparer.

Si vous ne voulez pas l'utiliser, ignorez-le. Si vous avez un bloc de code dont le succès dépend de chaque élément, mais que vous échouiez entre les deux, votre seule option consiste à intercepter la exception et à annuler ce qui doit être annulé. . Oubliez NotImplementedException . Des tonnes d'exceptions pourraient être générées, telles que MyRandomException et GtfoException et OmgLolException . Une fois que vous avez initialement écrit le code, je pourrais passer et jeter un autre type d’exception de l’API que vous appelez. Celui qui n'existait pas lorsque vous avez écrit votre code. Manipulez ceux que vous savez manipuler et annulez-les pour tous les autres, c'est-à-dire catch (Exception) . C'est assez simple, je pense ... Je trouve que c'est très pratique aussi. Surtout quand vous essayez des choses fantaisistes avec le langage / framework qui vous impose parfois des choses.

Un exemple que j'ai est la sérialisation. J'ai ajouté des propriétés dans ma bibliothèque .NET qui n'existent pas dans la base de données (par exemple, des wrappers pratiques sur les propriétés "stupides" existantes, comme une propriété FullName qui combine FirstName , MiddleName et Nom ). Ensuite, je souhaite sérialiser ces types de données en XML pour les envoyer par le fil (par exemple, d'une application ASP.NET à JavaScript), mais l'infrastructure de sérialisation sérialise uniquement les propriétés publiques avec get et < code> définir accesseurs. Je ne veux pas que vous puissiez définir FullName car je devrais alors l'analyser et il pourrait y avoir un format imprévu que j'analyserais à tort et l'intégrité des données disparaîtrait. Il est plus facile d’utiliser les propriétés sous-jacentes pour cela, mais comme le langage et l’API exigent que j’ai un accesseur set , je vais lancer une NotImplementedException (je n’étais pas au courant de NotSupportedException jusqu'à ce que je lise ce fil de discussion, mais que l'un des deux fonctionne). Ainsi, si un programmeur essaie de définir FullName , il rencontrera une exception lors des tests et réaliser son erreur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top