VB est-il vraiment insensible à la casse?

122

Je n'essaie pas de démarrer un argument ici, mais pour une raison quelconque, il est généralement indiqué que Visual Basic est insensible à la casse et que les langages C ne le sont pas (et c'est une bonne chose).

Mais voici ma question: où exactement Visual Basic est insensible à la casse? Quand je tape ...

Dim ss As String
Dim SS As String

... dans l' IDE de Visual Studio 2008 ou Visual Studio 2010 , le second a un avertissement de " La variable locale SSest déjà déclarée dans le bloc actuel ". Dans le VBA VBE, il ne déclenche pas immédiatement une erreur, mais corrige simplement automatiquement le cas.

Est-ce que je manque quelque chose ici avec cet argument que Visual Basic n'est pas sensible à la casse? (Aussi, si vous savez ou souhaitez répondre, pourquoi serait-ce une mauvaise chose?)

Pourquoi est-ce que je pose même cette question?

J'utilise Visual Basic dans plusieurs de ses dialectes depuis des années maintenant, parfois en tant qu'amateur, parfois pour des programmes liés aux petites entreprises dans un groupe de travail. Depuis six mois, je travaille sur un gros projet, bien plus important que ce que j'avais prévu. Une grande partie de l'exemple de code source est en C #. Je n'ai aucun désir ardent d'apprendre le C #, mais s'il y a des choses qui me manquent, les offres C # que Visual Basic ne fait pas (le contraire serait que VB.NET propose des littéraux XML ), alors j'aimerais pour en savoir plus sur cette fonctionnalité. Donc, dans ce cas, on fait souvent valoir que les langages C sont sensibles à la casse et que c'est bien et que Visual Basic est insensible à la casse et que c'est mauvais. J'aimerais savoir...

  1. Comment exactement est-ce que Visual Basic est insensible à la casse puisque chaque exemple dans l'éditeur de code devient sensible à la casse (ce qui signifie que la casse est corrigée) que je le veuille ou non.
  2. Est-ce suffisamment convaincant pour que j'envisage de passer à C # si le cas de VB.NET limite en quelque sorte ce que je pourrais faire avec du code?
Todd Main
la source
5
+1 Je me suis posé la même question avant.
NakedBrunch
7
Ummm ... pas sûr que vous compreniez ce que signifie sensible à la casse. Parce que VB est en fait insensible à la casse, SS et ss ont le même nom, alors qu'en C ils ne le seraient pas.
Ed S.20
1
@ed: Je ne peux pas utiliser les deux SSet ssen VB, celui que j'utilise en premier est celui que l'éditeur utilise.
Todd Main
1
Otaku, je recommande vivement de garder cette question centrée sur exactement ce que cela signifie de dire que VB est insensible à la casse et comment il est mis en œuvre. La question de savoir s'il vaut mieux qu'une langue soit insensible à la casse peut, malheureusement, déclencher une guerre des flammes. Si vous êtes vraiment curieux, posez-le dans une autre question. (Je vous conseille de ne pas le faire, mais si vous devez alors le taguer comme subjectif et le rendre wiki communautaire)
MarkJ
16
Vous pensez (ou étiez) à ce sujet à l'envers. C'est précisément parce que le compilateur est insensible à la casse que l'erreur lit «variable SS déjà déclarée». S'il était sensible à la casse, vous obtiendrez soit une 's variable non utilisée' ou aucune erreur du tout et un bogue si vous utilisiez alternativement l'un et l'autre.
Adriano Varoli Piazza

Réponses:

108

La différence entre VBA et VB.NET est simplement parce que VB.NET se compile en continu en arrière-plan. Vous obtiendrez une erreur lorsque vous compilerez le VBA.

Comme le dit Jonathan , lors de la programmation, vous pouvez considérer VB.NET comme insensible à la casse, à l'exception des comparaisons de chaînes, du XML et de quelques autres situations ...

Je pense que vous vous intéressez à ce qu'il y a sous le capot. Eh bien, le Common Language Runtime .NET est sensible à la casse , et le code VB.NET repose sur le runtime, vous pouvez donc voir qu'il doit être sensible à la casse lors de l'exécution, par exemple lorsqu'il recherche des variables et des méthodes.

Le compilateur et l'éditeur VB.NET vous permettent d'ignorer cela, car ils corrigent la casse dans votre code.

Si vous jouez avec des fonctionnalités dynamiques ou une liaison tardive (Option Strict Off), vous pouvez prouver que l'environnement d'exécution sous-jacent est sensible à la casse. Une autre façon de voir cela est de réaliser que les langages sensibles à la casse comme C # utilisent le même runtime, donc le runtime prend évidemment en charge la casse.

EDIT Si vous souhaitez retirer l'EDI de l'équation, vous pouvez toujours compiler à partir de la ligne de commande . Modifier votre code dans le Bloc - notes de sorte qu'il a sset SSvoir ce que fait le compilateur.

EDIT Citation de Jeffrey Richter dans les directives de conception .NET Framework page 45.

Pour être clair, le CLR est en fait sensible à la casse. Certains langages de programmation, comme Visual Basic, ne sont pas sensibles à la casse. Lorsque le compilateur Visual Basic tente de résoudre un appel de méthode à un type défini dans un langage sensible à la casse comme C #, le compilateur (pas le CLR) détermine la casse réelle du nom de la méthode et l'incorpore dans les métadonnées. Le CLR n'en sait rien. Désormais, si vous utilisez la réflexion pour vous lier à une méthode, les API de réflexion offrent la possibilité d'effectuer des recherches insensibles à la casse. C'est dans quelle mesure le CLR offre une insensibilité à la casse.

MarkJ
la source
Meilleure réponse que j'ai entendue jusqu'à présent. Existe-t-il un moyen de prouver ce point que le compilateur et l'éditeur VB.Net vous laissent ignorer ? Existe-t-il un moyen de désactiver la correction automatique? Ou existe-t-il un moyen de compiler un sln qui n'est pas écrit dans VS IDE dans MSBuild qui utilise à la fois sset SSet qui compilera et fonctionnera comme prévu?
Todd Main
5
Vous pouvez désactiver la correction automatique en trichant. Faites un clic droit sur un fichier vb et sélectionnez «Ouvrir avec». Ensuite, choisissez quelque chose comme "XML (Text) Editor". Vous perdrez toutes les fonctionnalités spécifiques à VB telles que la correction automatique.
Jonathan Allen
+1 excellente réponse, et bonne question aussi Otaku (je pense que vous le saviez déjà mais que vous vouliez en tirer une bonne définition hein?)
Type anonyme
Le compilateur / IDE VB.NET n'est pas 100% insensible à la casse. Par exemple, Dim pdfWriter As PDFWriterc'est tout à fait valable. VB.NET vous permet de faire la différence entre les noms de classe et les noms de variables, ce qui est une bonne idée, car c'est une pratique courante dans les langages entièrement sensibles à la casse.
ingrédient_15939
La méthode VB est la bonne pour l'interopérabilité. Exemple: créez une DLL en C # avec un e-mail sous forme de chaîne et Email () comme propriété avec l'événement inotifypropertychanged. C # se compilera correctement et la DLL sera générée. Essayez de référencer cette DLL en VB ou dans tout autre langage similaire. Cela indiquera qu'il y a un conflit dans la variable email / Email dans la bibliothèque. Les outils d'analyse de code signalent cela comme un problème dans le compilateur C # et non dans le compilateur VB.
Venkat
22

Une partie du problème ici est que vous devez séparer la langue de l'expérience IDE.

En tant que langage, VB.NET est certainement insensible à la casse en ce qui concerne les identifiants. L'appel DateTime.Parseet datetime.parsese liera exactement au même code. Et contrairement aux langages comme C #, il n'est pas possible de définir des méthodes ou des types qui ne diffèrent que par cas.

En tant qu'EDI, VB.NET tente de préserver la casse des identifiants existants quand il répertorie joliment un bloc de code. De jolies listes apparaissent chaque fois que vous vous éloignez de la ligne logique actuelle de code. Dans ce cas, vous quittez la deuxième déclaration de SS, le joli auditeur remarque qu'il existe un identifiant existant avec ce nom et le corrige pour qu'il corresponde à la casse.

Ce comportement, cependant, est purement fait comme une valeur ajoutée utilisateur. Cela ne fait pas partie du langage de base.

JaredPar
la source
1
Merci Jared, intéressant de savoir que ce n'est que l'IDE. Je n'arrive toujours pas à comprendre pourquoi ce serait une bonne chose d'avoir plus d'un nom représentant des choses différentes simplement par une différence de casse dans le nom, mais je suppose que c'est pour un autre jour.
Todd Main
1
Je ne pense pas que Jared voulait dire que ce n'était que l'IDE. Je pense qu'il a dit que le compilateur est insensible à la casse, donc il pense qu'il ssest identique à SS, mais aussi comme une aide à la lecture de l'IDE corrige SSau ssfur et à mesure que vous tapez. Ainsi, même si l'EDI ne corrigeait pas le cas, le compilateur verrait toujours les deux identificateurs comme identiques.
MarkJ
2
"Je n'arrive toujours pas à comprendre pourquoi ce serait une bonne chose d'avoir plus d'un nom représentant des choses différentes simplement par différence de casse dans le nom" <- J'ai ressenti la même chose avant de passer de VBA / VB6 / VB.NET à C # , Je pensais qu'avoir des noms ne différant que selon les cas semblait carrément dangereux. En pratique, cependant, il s'avère très utile et, étonnamment, pas du tout sujet aux erreurs.
Mike Rosenblum
2
@Mike Je ne suis pas du tout d'accord avec ce point. Je n'ai jamais vu de noms mixtes qui ne faisaient que semer la confusion.
JaredPar
2
Vraiment? Je veux dire quelque chose comme void SetColor (color Color) {this.color = color}; Je me rends compte que cela peut sembler dangereux, mais cela fonctionne bien, le compilateur ne vous laissera pas faire d'erreur et IntelliSense vous donne les bons membres après "couleur". vs "Couleur". Ce qui me dérange ici, c'est que l'utilisation de "this" n'est pas requise - elle est appliquée par FxCop et / ou StyleCop (j'oublie lequel), mais j'aurais aimé qu'il y ait un paramètre pour que l'EDI applique toujours cela lors de l'accès à la classe membres au lieu de permettre potentiellement l’observation accidentelle de la portée.
Mike Rosenblum
16

VB est généralement insensible à la casse, mais il existe des exceptions. Par exemple, les littéraux XML et la compréhension sont sensibles à la casse. Les comparaisons de chaînes sont généralement sensibles à la casse, contrairement à T-SQL, mais il existe un commutateur de compilateur pour rendre les comparaisons de chaînes insensibles à la casse. Et bien sûr, il existe des cas extrêmes en ce qui concerne l'héritage, COM et Dynamic Language Runtime.

Jonathan Allen
la source
3
Les bons points sur où la casse importe comme les littéraux XML et les comparaisons de chaînes. Mais quand nous disons qu'il est généralement insensible à la casse, de quoi parlons-nous exactement? Passant à Outlook VBA, à titre d'exemple, si je tape Dim mi as mailitemet subject = mi.subject, les noms d'objet seront automatiquement corrigés en MailItemet mi.Subject. Le compilateur s'en soucie-t-il (car il corrigera toujours automatiquement cela) ou est-ce joli code ou ...?
Todd Main
1
Le compilateur s'en fiche. Vous pouvez tester cela en éditant un fichier dans le bloc-notes et en utilisant le compilateur de ligne de commande.
Jonathan Allen
9

Oui, le compilateur VB.NET traite les identificateurs d'une manière insensible à la casse. Et oui, cela peut causer des problèmes lorsqu'il utilise des assemblys écrits dans un autre langage ou utilise des composants COM. Le premier cas est couvert par la spécification de langage commun . La règle pertinente est:

Pour que deux identifiants soient considérés comme distincts, ils doivent différer par plus que leur cas.

Le cas COM est assez grossièrement pris en charge par le constructeur de la bibliothèque de types, il force la casse des identificateurs de même nom à être identiques. Même lorsque ces identifiants ont des rôles différents. En d'autres termes, un paramètre de méthode avec le nom "index" forcera un nom de méthode "Index" à être recasé en "index". Cela a produit beaucoup de grattage à la tête, comme vous pouvez l'imaginer :)

Hans Passant
la source
6

VB préserve la casse (dans l'EDI) mais insensible à la casse . C'est comme le système de fichiers Windows d'une certaine manière. Hello.txt et hello.txt sont considérés comme étant le même nom de fichier.

L'EDI suppose que la déclaration d'une variable est le cas "correct" pour cette variable et ajuste chaque instance de cette variable correspondant à la déclaration. Il le fait pour des raisons de beauté et de cohérence, mais pas pour la fonctionnalité.

J'ai vu plusieurs cas où le cas n'a pas été automatiquement modifié pour correspondre à la déclaration, et l'instruction fonctionne de la même manière. Vous pouvez également utiliser n'importe quel éditeur de texte pour écrire du code qui se compilera très bien dans différents cas.

Une remarque:

La plupart des PEOPLE pensent d'une manière insensible à la casse. Quand nous voyons le mot «chien», le mot est traduit en sens dans notre esprit. La signification du mot n'est pas basée sur la casse (c'est-à-dire que l'épeler "DOG", "DoG" ou "DOG" aboie toujours.) LES ORDINATEURS voient les mots comme des sacs discrets de bits. Les majuscules et les minuscules sont des modèles de bits différents, et sont donc différents.

Comme la plupart des programmeurs sont humains, l'insensibilité à la casse semble plus adaptée à la façon dont les gens pensent et la sensibilité à la casse consiste davantage à adapter leur façon de penser aux contraintes d'une machine.

Andrew Neely
la source
4
Sauf que les programmeurs ont besoin de faire la distinction entre les objets et les classes, et ont traditionnellement utilisé un changement de casse pour le faire (pas obligatoire, juste une convention). Donc, object.method()et Object.Method()sont instantanément reconnus comme des références et des méthodes d'objet et de classe (si vous vous conformez à cette convention de codage). Comme en anglais, vous distinguez les noms propres et les débuts de phrases par une lettre majuscule. Donc, lors de la lecture ou de la programmation, je ne pense pas à la casse de manière insensible, sinon je manquerais de sens.
Jason S
@Jason, tout dépend de ce à quoi vous êtes habitué. Les nouveaux étudiants en programmation C proposent une myriade de plaintes sur la sensibilité à la casse au début, puis, après quelques cours, s'y habituent. Les objets object.method () et Object.Method () ne sont qu'une convention et constituent le cas le plus fort pour le respect de la casse. J'ai dû modifier un programme écrit par quelqu'un d'autre qui avait deux variables nommées temp et Temp dans la même portée, et je vais vous dire qu'il était très difficile de les garder dans ma tête. Et tandis que nous pouvons reconnaître un nom commun par capitalisation, les mots «bob» et «Bob» signifient la même chose dans notre cerveau.
Andrew Neely
Pourquoi l'EDI préserve-t-il le cas dans ce cas? (Désolé). Je pense que l'EDI préserve le cas parce que les concepteurs de MS pensent que le cas a une certaine sémantique, dans le cerveau, ce qu'il fait. Mais en réalité , le VB IDE considère formet Formmême, ce qui est à moi en tout cas, la confusion. Dans le cas (encore désolé), de tempet Tempvous pouvez facilement utiliser les outils de refactoring en C # pour renommer Tempà bobTempou autre. Cependant, je maintiens un peu de VB et quelqu'un est parti et fait Dim form As Form. Maintenant, lorsque je renomme, il renomme à la fois les références de classe et d'objet. Bleah!
Jason S
@Jason, en VB je dis toujours "Dim aform as Form", mais je m'éloigne du sujet. VB prend en charge la sensibilité à la casse lors de la recherche. Aussi je chercherais "As Form" et le remplacerais par "somethingstupid", puis je renomme la forme en quelque chose de sensé, puis je renomme "somethingstupid" en "As Form". J'aime en fait changer la casse, car cela vérifie que je n'ai pas graissé le nom de la variable.
Andrew Neely
Ouais, mais cela ne remplace pas un outil de refactorisation qui distinguera la référence de classe et d'instance lorsque les noms sont identiques (ou ne diffèrent que par cas dans VB). Les outils de refactoring C # semblent pouvoir le faire. Je ne nomme pas les classes et les instances de la même manière. En C #, j'utiliserai la casse pour faire la distinction, mais en VB, je ne peux pas le faire, alors j'utilise des lettres en préfixe. Évidemment, mon problème est que je gère le code de quelqu'un d'autre qui a utilisé le même nom. Mais cette discussion devient trop grande pour les commentaires, je vais donc la laisser ici.
Jason S
5

Cela fait partie de l'éditeur que vous utilisez, ils peuvent se comporter différemment, mais le fait est que Visual Basic est vraiment un langage insensible à la casse. Donc, sset SSsont les mêmes.

Veuillez consulter le didacticiel VB.NET Basics pour plus d'informations :)

Sarfraz
la source
Oh c'est intéressant. y a-t-il un endroit où je regarde ce détail? Je n'ai pas encore testé, mais en pensant à VBScript, vous avez peut-être raison.
Todd Main
@Otaku: s'il vous plaît voir ma réponse à nouveau, j'ai fourni le lien maintenant. Merci
Sarfraz
Je connais assez bien VB, merci :) Je ne suis pas sûr de ce que vous voulez que je regarde sur cette page.
Todd Main
3

Je ne suis pas sûr de vous comprendre? VB est insensible à la casse, donc ss et SS sont la même variable, donc le compilateur se plaint correctement que vous avez re-déclaré la variable.

Je pense que les variables ne sont pas sensibles à la casse, mais les noms de fonctions le sont.

Michael Stum
la source
mais si j'utilise sset puis tapez plus tard SS, il est automatiquement corrigé ss, ce qui me porte à croire que le compilateur se soucie effectivement du cas.
Todd Main
5
@oTAKU: C'est l'IDE qui change la casse, pas le compilateur.
John Saunders
2
VB ne se soucie toujours pas vraiment de l'affaire. L'EDI tente de nettoyer le code pour que les variables restent les mêmes partout.
guitarthrower
1

Oui, VB est insensible à la casse. Il jette parfois ceux qui n'y sont pas habitués pendant une petite boucle.

Xorlev
la source
1

Il n'est pas nécessaire d'essayer tout ce que dur dans VB.NET pour créer du code avec différentes «orthographes» majuscules / minuscules d'un identifiant. Changer la casse d'un identifiant dans le fichier où il est déclaré sans utiliser la fonction "Renommer" ne provoquera pas la mise à jour du nom dans d'autres fichiers, bien que la modification de toute ligne contenant le nom le rendra conforme à la définition actuelle.

De cette façon, on peut déterminer que VB.NET est généralement insensible à la casse, mais il met la casse des identificateurs à la disposition du CLR qui peut utiliser ces informations de manière sensible à la casse.

supercat
la source
1

Je ne peux que proposer ceci, ce qui, comme je me souviens de mes manuels de programmation au début des années 80, est que les langages sensibles étaient, (à l'époque) strictement destinés à réduire les erreurs de compilation. C'est-à-dire que la «rigueur» visait à développer une discipline de codage plus précise. Comme il s'est avéré que l'ajout d'un étiquetage approprié des variables, des classes, des méthodes, des fonctions et tout ce que vous souhaitez y ajouter a également évolué.

Je me souviens que presque tous ces livres incluaient un modèle recommandé pour les majuscules, les minuscules, etc. Comme nous le savons tous, une grande partie de cela a été jetée ou devrais-je dire, ignorée dans la pratique, à l'exception des maisons de production haut de gamme, et Solutions CASE, ou pour ceux qui ont atteint un niveau de compétence plus élevé. Je pense que tout le monde vit cette courbe d'apprentissage.

Compte tenu de l'avancement de ces langages et IDE, la meilleure question devient, quelle langue améliore mon temps de développement? Bien sûr, si vous n'êtes pas familier avec chacun des différents langages, vos options sont limitées.

htm11h
la source
1

Je vais essayer de répondre à votre deuxième question.

"Est-ce suffisamment convaincant pour que j'envisage de passer à C # si le cas de VB.NET limite en quelque sorte ce que je pourrais faire avec du code?"

Créez un WebService WCF à l'aide de C #. Créez un DataContract (1 classe). Un avec la propriété "string email". Un autre avec "string Email" comme autre propriété. Votre choix de comprendre comme e-mail personnel ou e-mail de bureau. Ou cela pourrait être dans deux DataContracts différents.

Pour C # c'est très bien. Le service Web est bien créé. Le programme AC # peut facilement créer un WSDL et tout va bien.

Essayez maintenant de créer un WSDL avec VB (n'importe quelle version). Il indiquera que «l'email» est déjà déclaré et la génération WSDL échoue.

Comme tout le monde, j'ai supposé que c'était un inconvénient en langage VB. Mais!!!

Utilisez FxCOP et analysez le code C # d'origine. FxCOP dit que l'utilisation du courrier électronique / courrier électronique est un problème. Recommande d'utiliser un nom différent prenant en charge l'insensibilité à la casse. Notez également qu'à ce jour, le framework .NET dispose de 106 langages de programmation et que de nombreux langages ont la sensibilité à la casse activée. Nous évoluons tous vers le cloud et souhaitons que nos services soient accessibles par toutes les plates-formes / langages de programmation.

Donc, être sensible à la casse est votre choix dans votre programme et si vous êtes un gars C, vous l'aimeriez. Si le programme doit être utilisé / accédé par d'autres programmes non C, vous devez prendre en charge l'insensibilité à la casse, mais votre langue est votre choix.

http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Visual_Basic_.NET http://www.vbrad.com/article.aspx?id=65

Venkat
la source
Le cloud utilise des URI sensibles à la casse (ce qui est particulièrement important pour les proxys et les serveurs de cache).
binki
1

Le masquage des symboles (par exemple, le champ de masques locaux) est également insensible à la casse.

Voici un exemple :

Public Class C
    Public Name As String

    Public Function M(name As String) As Boolean
        Return String.Equals(name, Name) ' case differs
    End Function
End Class

La sortie du compilateur VB.NET est décompilée (et donc équivalente à) le C # suivant:

public class C
{
    public string Name;

    public bool M(string name)
    {
        return string.Equals(name, name); // both lowercase
    }
}

string.Equalsest passé le champ deux fois. Le local est caché, quel que soit le cas. Le langage est insensible à la casse.

Pour référencer explicitement le membre a, comme ce champ, vous devez déréférencer le membre via Me:

Return String.Equals(name, Me.Name) ' differentiate field from local
Drew Noakes
la source
0

Je n'ai vu personne commenter votre deuxième question explicite à la fin: "2: est-ce suffisamment convaincant pour que j'envisage de passer à C # si le cas de VB.NET limite en quelque sorte ce que je pourrais faire avec du code?"

Je préfère l'approche plus d'options que C # laisse le programmeur choisir de limiter les options du programmeur. Je préfère fortement C #, mais pour la seule sensibilité à la casse, je ne le penserais même pas proche d'apprendre un langage simplement parce qu'il est sensible à la casse. toutes les fonctionnalités sont ce qui compte, et quand je regarde les avantages des deux, C # et VB.NET, je préfère fortement C #. mais je vais vous donner une vraie perspective équilibrée, biaisée oui, car j'ai une préférence, mais je serai honnête sur les inconvénients de C # aussi.

tout d'abord, les deux langues présentent des avantages et des inconvénients. les différences que vous pouvez faire dans une langue qui ne peuvent pas être faites dans l'autre diminue car, heureusement, Microsoft améliore les deux langues, et ils ne semblent pas montrer de partialité injuste envers l'une ou l'autre langue.

lorsque C # est sorti pour la première fois, VB n'avait pas ses commentaires XML que vous pouviez mettre avant les méthodes, ce que j'ai adoré en C #. je détestais ça dans VB.NET. mais j'ai vu au fil des ans, que de nombreuses fonctionnalités qui ne sont pas dans une langue s'ajoutent à l'autre. (la même équipe de développeurs MS développe à la fois C # et VB, il est donc logique que les fonctionnalités deviennent assez similaires.)

mais vous avez demandé ce que C # a que VB n'a pas. en voici quelques-uns auxquels je peux penser immédiatement:

1: C # est plus concis et prend moins de frappe .. de plusieurs façons! J'ai même vu la stupidité parler quand la prétention opposée est faite, que VB sauve la frappe. mais écoutez les personnes qui vous disent qu'elles utilisent les deux langues et qu'elles ne l'utilisent que rarement. j'utilise à la fois C # etVB, C # à la maison parce que je l'aime (et quand je travaille avec C # au travail), et mes demandes d'emploi plus récentes que j'utilise VB et non C #. Je reçois donc une utilisation plus fréquente de VB maintenant (depuis environ 10 mois maintenant), mais dans mon témoignage personnel, je préfère de loin C #, et en termes de frappe réelle, VB est considérablement plus typée. le seul exemple que j'ai lu où quelqu'un a en fait essayé de dire que VB était plus concis, donnait un exemple «avec ...» avec une longue variable dans le avec, donc en VB, vous pourriez simplement utiliser «.property». il est stupide de prétendre que VB a besoin de moins de frappe. il y a quelques choses (et pas seulement cet exemple) où VB est plus court, mais beaucoup plus de fois où C # est plus concis, dans la pratique réelle.

mais la principale raison pour laquelle je pense que C # est plus concis, ce sont les déclarations verbeuses "IF / THEN" de VB. si les déclarations sont courantes. en C # il n'y a pas de mot «alors» à taper! :) aussi toutes les instructions 'end ...' prennent un typage qui en c #, n'est généralement qu'une accolade fermante '}'. J'ai lu que certaines personnes prétendent que cette plus grande verbosité dans VB.NET est un avantage pour VB car plusieurs instructions / symboles de bloc de fermeture peuvent être imbriqués et se terminer immédiatement les uns à côté des autres, mais je ne suis pas du tout d'accord. une personne peut presque toujours écrire un programme mieux en C # ou en VB qu'un autre programmeur car la prochaine révision de code pourrait être mieux conçue. cela s'applique à la «confusion de nombreuses accolades fermantes en C #» plus si les blocs imbriqués sont tous du même type que plusieurs IF imbriquées, alors VB souffre du même problème qu'en C #. ce n'est pas un avantage en VB. cette situation est précisément la raison pour laquelle j'aime commenter ce que mon symbole de clôture ou mon énoncé de clôture va de pair dans les deux langues. oui, c'est plus détaillé à faire, mais dans l'une ou l'autre langue, vous avez la possibilité d'être clair, ce qui est important dans les cas spécifiques basés sur le jugement et la situation. Je pense que la clarté du code est assez importante.

2: VB n'a pas de commentaires sur plusieurs lignes. quand je travaillais avec VB, cela ne me dérangeait pas. puis je suis allé à quelques langages de style C. maintenant, je suis de retour principalement en utilisant VB.NET au travail, et ils me manquent. c'est juste quelque chose que vous trouvez pratique et que vous devez ensuite perdre. :(

3: 'andalso' et 'orelse' de VB est assez ennuyeux de taper tout cela quand en C # c'est simplement '&&' et '||'. encore une fois, moins de frappe. ce n'est pas rare dans mon code en VB et C #. si quelque chose, pour la fonctionnalité, 'OR' vs 'OrElse' n'a généralement pas d'importance sauf que 'OrElse' est plus rapide pour l'ordinateur, donc si un programmeur utilise simplement 'Or' et 'Et' dans VB, alors il produit un code moins optimal pour quelqu'un qui aime la clarté du code. «Ou» est beaucoup plus facile à parcourir que «OrElse».

4: plus de flexibilité dans le placement du code en C #. quand une ligne est longue et que vous voulez l'envelopper sur la ligne suivante, je déteste le réajustement de contrôle de mon code par VB.NET. C # le fait un peu, mais je le trouve plus utile en C #, où en VB, c'est beaucoup plus contrôlant. mais il s'agit davantage de l'IDE VB.NET vs IDE C # plutôt que du langage lui-même. mais je ne sais pas si vous voulez les deux ou uniquement les fonctionnalités linguistiques sans différences IDE.

5: celui qui me manque vraiment est simplement de créer un nouveau bloc de code en C #, il se peut que beaucoup de choses se passent dans une méthode et je veux déclarer une variable dans un très petit bloc de code mais ne pas déclarer cette variable en dehors de ce bloc dans toute la méthode. en C #, nous pouvons simplement créer un nouveau bloc avec '{' et le terminer par '}'. VB n'a pas une telle fonctionnalité, mais sa correspondance la plus proche est un bloc inconditionnel «If True Then» et «End If». (notez à nouveau l'équivalent de 2 caractères C # vs 18 caractères VB.NET ... plus de saisie en VB.)

6: opérateurs d'auto-incrémentation et de décrémentation: ++ et - comme dans myVariable++ou ++myVariableou les versions de décrémentation équivalentes. cela est très pratique ... parfois. voici un exemple de code réel lorsque j'ai beaucoup manqué C #:

// C#:
while (txt.Length > x)
{
    thisChar = txt[x];
    if (charsAllowedWithoutLimit.Contains(thisChar)) { ++x; }
    else if (allowLettersWithoutLimit && char.IsLetter(thisChar)) { ++x; }
    else if ((x2 = charsAllowedWithLimit.IndexOf(thisChar)) >= 0)
    {
        ++x; if (++usedCountA[x2] > charAllowedLimit[x2]) { break; }
    }
    else { break; }
}

' VB.NET:
While (txt.Length > x)
    thisChar = txt(x)
    If (charsAllowedWithoutLimit.Contains(thisChar)) Then
        x += 1
    ElseIf (allowLettersWithoutLimit AndAlso Char.IsLetter(thisChar)) Then
        x += 1
    Else
        x2 = charsAllowedWithLimit.IndexOf(thisChar)
        If (x2 >= 0) Then
            x += 1
            usedCountA(x2) += 1S
            If usedCountA(x2) > charAllowedLimit(x2) Then Exit While
        Else
            Exit While
        End If
    End If
End While

Et juste pour donner un TRES bon exemple de règles C #, c'est plus de code que j'ai personnellement écrit récemment:

// C#
public static bool IsNotWithin(this Byte   v, Byte   v1, Byte   v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this SByte  v, SByte  v1, SByte  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int16  v, Int16  v1, Int16  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int32  v, Int32  v1, Int32  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int64  v, Int64  v1, Int64  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt16 v, UInt16 v1, UInt16 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt32 v, UInt32 v1, UInt32 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt64 v, UInt64 v1, UInt64 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Decimal v, Decimal v1, Decimal v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }

public static bool IsWithin(this Byte   v, Byte   v1, Byte   v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this SByte  v, SByte  v1, SByte  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int16  v, Int16  v1, Int16  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int32  v, Int32  v1, Int32  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int64  v, Int64  v1, Int64  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt16 v, UInt16 v1, UInt16 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt32 v, UInt32 v1, UInt32 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt64 v, UInt64 v1, UInt64 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Decimal v, Decimal v1, Decimal v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }

' And the VB equivalent is a mess! Here goes:
<Extension()>
Public Function IsNotWithin(v As Byte, value1 As Byte, value2 As Byte) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As SByte, value1 As SByte, value2 As SByte) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As Int16, value1 As Int16, value2 As Int16) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

' the % suffix means 'As Integer' in VB.
<Extension()>
Public Function IsNotWithin(v%, value1%, value2%) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

' the & suffix means 'As Long' in VB.
<Extension()>
Public Function IsNotWithin(v&, value1&, value2&) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As UInt16, value1 As UInt16, value2 As UInt16) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As UInt32, value1 As UInt32, value2 As UInt32) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As UInt64, value1 As UInt64, value2 As UInt64) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

' the @ suffix means 'As Decimal' in VB.
<Extension()>
Public Function IsNotWithin(v@, value1@, value2@) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsWithin(v As Byte, value1 As Byte, value2 As Byte) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As SByte, value1 As SByte, value2 As SByte) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As Int16, value1 As Int16, value2 As Int16) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

' the % suffix means 'As Integer' in VB.
<Extension()>
Public Function IsWithin(v%, value1%, value2%) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

' the & suffix means 'As Long' in VB.
<Extension()>
Public Function IsWithin(v&, value1&, value2&) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As UInt16, value1 As UInt16, value2 As UInt16) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As UInt32, value1 As UInt32, value2 As UInt32) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As UInt64, value1 As UInt64, value2 As UInt64) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

' the @ suffix means 'As Decimal' in VB.
<Extension()>
Public Function IsWithin(v@, value1@, value2@) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

C'est peut-être une preuve suffisante que C # est plus concis. Mais tous les programmeurs n'aiment pas la concision. Certains préfèrent lire "si a <b alors ..." parce que c'est plus naturel pour leur langage humain. Et c'est très bien. Les préférences sont bien. Pour moi, l'effort de la main est une valeur du facteur i, et je pense que n'importe qui peut s'habituer à penser dans les symboles qu'il préfère, car "si" et "alors" sont des symboles d'un alphabet et "si (condition) instruction;" de C #; la syntaxe sont aussi des symboles. l'un est juste plus proche de la syntaxe d'un non-programmeur que l'autre. je préfère le concis.

Je pense aussi que le besoin d'utiliser «c» après les littéraux de caractères dans VB pour en faire un littéral de caractère plutôt qu'une chaîne est ennuyeux. J'aime bien plus la concision de C #. lorsqu'une méthode nécessite un caractère littéral, vous devez fournir un caractère et non une chaîne avec une longueur de caractère, donc parfois vous êtes obligé de l'utiliser ":"cen VB alors qu'en C # c'est le cas ':'. Je pense que c'est un peu difficile.

Pour être juste, je dirais qu'il ya des avantages que j'aime VB comme ne pas avoir à mettre entre parenthèses vides après les appels de méthode, comme Dim nameUpper$ = name.ToUpperInvariantoù C # exige que les parenthèses vides: string nameUpper = name.ToUpperInvariant(). soit le double que , comme la coupe trop: Dim nameUpper$ = name.Trim.ToUpperInvariantvs string nameUpper = name.Trim().ToUpperInvariant(). J'aime l'utilisation concise par VB de la façon dont je viens de l'utiliser$ ci-dessus pour le réduire `` As String '' où C # n'a pas ces raccourcis. VB a ces raccourcis pour les types String, Integer, Long, Decimal, Single et Double, mais l'inconvénient est qu'il est moins clair, donc je l'utilise avec prudence. mais néanmoins, je préfère un code concis.

Eh bien, ce ne sont que quelques thots de ce programmeur chevronné, et comme je le considère, c'est mon `` témoignage '' de programmation de C # vs VB. les deux sont de belles langues tho, à mon avis. mais oui, je préfère toujours beaucoup C #.

ps Puisque je prévois de programmer la majeure partie de ma vie, j'ai même réappris à taper en utilisant le clavier le plus efficace: le clavier Dvorak, qui demande environ 1/3 d'effort pour taper l'anglais que sur un clavier Qwerty. Cherchez-le. peut-être que vous voudrez peut-être changer aussi. ;) cela a rendu ma frappe 67% plus facile! :) J'encourage tout le monde à sortir des sentiers battus et à évaluer une meilleure efficacité dans votre travail. La disposition de clavier simplifiée Dvorak et C # l'ont fait pour moi. :)

PSS i comparerait le Dvorak et C # à la métrique par opposition à la disposition du clavier Qwerty et VB aux mesures Empirial. Dvorak, métrique et C # sont simplement «propres». MAIS VB n'est pas vraiment loin derrière. Mais il souffre de la nécessité d'être rétrocompatible avec l'ancien code VB6 et le code pré .NET, comme le 'Or' vs 'OrElse' et 'IIF ()'.

Je termine avec une prudence. Soyez plus prudent que d'écouter des gens qui ne savent pas vraiment de quoi ils parlent. La moitié de tous les inconvénients contre VB et C # sont ne pasaucun problème, et les gens continuent de signaler qu'ils ignorent les inconvénients qui existent encore dans la langue. Le meilleur exemple auquel je puisse penser est celui des commentaires XML pour les méthodes utilisant une triple apostrophe en VB ou des symboles de commentaire triple barre oblique en C #. Mais s'il vous plaît, discernez par vous-même si une personne parle par ignorance ou par expérience. Le témoignage personnel signifie qu'ils savent de leur expérience réelle. Et une fois que quelqu'un a beaucoup d'expérience dans ce domaine, réveillez vos oreilles. J'ai plus de 10 ans d'expérience en C # et VB. Et cela se résume à ceci: les deux sont de (très) bonnes langues. Et la plupart des différences, vous pouvez voir immédiatement dans les 5 minutes suivant la lecture du code. Mais oui, d'autres fonctionnalités peuvent mettre des années à trouver un handicap. Et un handicap dont je suis conscient (en C #), je peux ' t même penser à une situation réelle où cela serait utile. Ce n'est donc peut-être pas un handicap après tout.

Bon codage!

Shawn Kovac
la source
J'apprécie tous les détails, mais votre exemple n'utilise pas la sensibilité à la casse / insensibilité (pour autant que je sache) pour montrer pourquoi C # est en quelque sorte «meilleur».
Todd Main
J'ai essayé de répondre à la deuxième question par un exemple direct.
Venkat le
@ToddMain, c'est correct. Et mon exemple n'utilise pas la sensibilité à la casse pour montrer pourquoi C # est meilleur parce que la question ne demande pas pourquoi la sensibilité à la casse le rend meilleur. D'ailleurs, je pense que cette fonctionnalité parle d'elle-même. Et je crois que la logique est fondamentale pour que la plupart des gens puissent en déduire eux-mêmes. Mais si quelqu'un demande, je suis heureux de l'aider à passer à travers la logique. Mais cela, mon ami, à mon avis, est une question différente. ;)
Shawn Kovac
En fait, c'était l'une des deux questions posées dans le message d'origine. Ce n'est pas évident, c'est pourquoi j'ai demandé. Mais ne vous inquiétez pas de ne pas répondre à la question.
Todd Main
@ToddMain, je vois votre point. point très juste en effet. :) Merci d'avoir ouvert les yeux là-dessus. :)
Shawn Kovac
0

VB.NET est sensible à la casse.

Exemples:

1.

Dim a As Integer
Dim A as Integer

2.

Sub b()
    'Some statement(s) here
End Sub
Sub B()
    'Some statement(s) here
End Sub

3.

Function c() As Integer
    'Some statement(s) here
End Function
Function C() As Integer
    'Some statement(s) here
End Function

Tous ces codes généreront une ERREUR DE COMPILATION .

Pour le premier exemple, une erreur sera affichée, disant "La variable locale 'A' est déjà déclarée dans le bloc courant.".

Alors que pour le 2ème et le 3ème exemple, une erreur sera affichée en disant "'Public Sub b ()' a plusieurs définitions avec des signatures identiques." et "'Public Function c () As Integer' a plusieurs définitions avec des signatures identiques.", respectivement.

À partir de ces erreurs, notez que les erreurs sont lancées à différentes positions pour les variables et les procédures / fonctions. Pour les variables, l'erreur est lancée à la 2ème déclaration tandis que pour les procédures / fonctions, elle est lancée à la 1ère déclaration / définition de code identique.

Comme l'a dit un utilisateur dans un commentaire quelque part ci-dessus, le code VB.NET est continuellement vérifié et / ou corrigé en arrière-plan; vous pouvez voir cette erreur dans la fenêtre "Liste des erreurs" dans VS IDE. Et comme c'est une erreur et non d'un avertissement , le code ne se compilera pas tant que l'erreur ne sera pas résolue.

Nikunj Bhatt
la source