2
votes

Comment afficher une erreur lors de l'utilisation de non chaînes comme chaînes (au lieu d'une utilisation automatique de ToString)?

Le doublon suggéré est en effet une question similaire. Cependant, la réponse ne couvre qu'une seule option: désactiver le ToString () lui-même. Il existe d'autres solutions possibles, comme demander à Visual Studio de m'en avertir, ou faire en sorte que ToString () ne soit pas appelé (lisez attentivement la réponse, il suppose qu'il est appelé, et explique simplement qu'il y a aucun moyen de "supprimer" ToString ().), ou d'utiliser une version inférieure de C # (cela a-t-il toujours fonctionné de cette façon?), etc ...

Quand j'ai une non chaîne quelque part où une chaîne est attendue par le code Je ne veux pas qu'il soit automatiquement converti en chaîne. Je veux une erreur. Par exemple:

public string Stringify()
{
    return Data + Environment.NewLine;
}

Et Data est un octet [] JE NE VEUX PAS obtenir: p >

System.Byte []

Je veux obtenir une erreur donc je sais que je dois la corriger. (Il y a une raison pour un typage fort.)

Alors, y a-t-il un moyen d'obtenir Visual-Studio / C # /. Net pour me montrer une erreur / throw-an-Exception lors de l'utilisation de non chaînes comme chaînes?


9 commentaires

Possibilité de duplication de est-il possible de désactiver l'appel implicite ToString ()?


Vous pouvez toujours écrire votre propre Roslyn Analyzer et détecter les appels .ToString () implicites sur des objets non String. Probablement pas une solution simple pensée.


@Thowk Merci! Bien que je sois d'accord que ce n'est pas une solution simple, c'est la première vraie réponse à ma question. N'hésitez pas à le poster comme réponse. Vaut vraiment un vote positif.


@ispiro Pouvez-vous mettre à jour un peu la question? Vous vous plaignez d'une frappe forte, mais vous autorisez Data à être de n'importe quel type. Si Data est déclaré comme une chaîne alors ce sera toujours une chaîne et le compilateur se plaindra déjà lorsque vous en abuserez.


Il existe déjà un analyseur Rosyln qui génère des avertissements lors de l'utilisation implicite de ToString sur un objet qui n'a pas remplacé ToString ici github.com/Microsoft/Rosyln-Analyzer-ToStringWithoutOverride écrit par Microsoft. Je n'ai pas d'expérience avec les analyseurs Rosyln, donc quelqu'un d'autre pourrait transformer cela en une réponse à part entière.


@MichaelPuckettII Ma question concerne spécifiquement quand une variable n'est pas une chaîne et que je l'utilise par erreur là où une chaîne est attendue. Tout comme si vous aviez int i = someString + 1 , vous obtiendrez toujours une erreur, alors j'aimerais avoir ici.


@TJRockefeller Très bien! Je pense que Microsoft devrait avoir une option comme celle intégrée à VS.


@ispiro Ok, je pense que je comprends mieux maintenant. Dans cet esprit, je pense que l'analyseur Roslyn fonctionne comme une réponse.


@ IvanFerić j'aurais aimé qu'il en soit ainsi ....


3 Réponses :


0
votes

Vous pouvez explicitement essayer de diffuser des données et VS se plaindra s'il ne s'agit pas d'une chaîne

public string Stringify()
{
    return (string)Data + Environment.NewLine;
}


1 commentaires

Si je remarquais que ce n'est pas une chaîne, je le réparerais déjà. Si vous suggérez que je m'habitue à faire ça tout le temps partout - cela aiderait en effet, mais c'est à mon humble avis trop de travail.



0
votes

Lorsque vous avez un type string et que vous utilisez l'opérateur + , il appellera le virtuel ToString () code > méthode pour tout type qui n'est pas une chaîne automatiquement.

Vous ne pouvez pas éviter cela en ajoutant simplement des types pour produire une chaîne (du moins pas de manière simple ou pratique).

Vous pouvez faire autre chose à la place; comme

public string Stringify(string data)
{
    return data + Environment.NewLine;
}

Si vous voulez vous assurer que Data est toujours une chaîne sans test, je le passerai à la méthode comme paramètre.

return (Data is string value) 
       ? value + Environment.NewLine
       : throw new Exception("Not a string"); //or return whatever else you want here.

Et le cas évident; si vous voulez que Data soit un champ et toujours une chaîne , il faut déclarer Data comme une chaîne pour commencer .

Modifier:

Comme indiqué dans les commentaires ci-dessus; Je comprends maintenant que vous voulez essentiellement signaler toute utilisation des appels virtuels ToString () pour empêcher que de telles opérations ne se produisent. Un commentaire a été donné pour mettre à jour l'analyseur Roslyn et un lien vers l'endroit où cela a déjà été fait auparavant. Je ne poste pas ces commentaires ici pour voler la réponse, mais je suis d'accord que, c'est peut-être la meilleure solution pour ce que vous voulez. Une autre option serait d'utiliser la réflexion mais cela ne fonctionnerait pas avant l'exécution.


4 commentaires

(Pas le downvoter) Voir mon commentaire sur l'autre réponse s'il vous plaît.


@ispiro Ok, alors peut-être que je comprends mal la question. Que voulez-vous qu'il se passe exactement?


Je veux que dans le cas où j'écrirais le code incriminé (parce que j'ai oublié de transformer Data en hexadécimal ou autre) pour obtenir une sorte de notification afin que je sache besoin de le réparer. Tout comme lorsque j'utilise le mauvais type n'importe où ailleurs en C #.


Ensuite, je suggère de toujours passer Data à la méthode en tant que paramètre string .



1
votes

Les analyseurs Rosyln peuvent être installés dans votre projet à l'aide de Nuget dans Visual Studio 2017.

En particulier, il existe un analyseur Rosyln qui vérifie les appels implicites et explicites à ToString () si ToString () n'est pas écrasé dans la classe. https://www.nuget.org/packages/ToStringWithoutOverrideAnalyzer/

Les analyseurs installés peuvent être trouvés sous les références

 entrez la description de l'image ici

Par défaut, cet analyseur produira des avertissements comme indiqué par le triangle avec ! , mais en cliquant avec le bouton droit sur les règles, vous pouvez élever n'importe quelle règle en erreur, ou la réduire en information.

Obstacle potentiel

Console.Write et Console.WriteLine ont plusieurs surcharges, y compris Console.Write (valeur d'objet) , donc si vous imprimez un objet qui n'a pas remplacé ToString () comme Console.Write (myCustomObject) l'analyseur ne le détectera pas car il n'y a pas de conversion implicite en cours (du moins dans le code qui vous avez écrit)


0 commentaires