Czy VB naprawdę nie rozróżnia wielkości liter?


122

Nie próbuję tu zaczynać argumentacji, ale z jakiegoś powodu zwykle stwierdza się, że Visual Basic nie rozróżnia wielkości liter, a języki C nie (i jakoś to dobrze).

Ale oto moje pytanie: gdzie dokładnie wielkość liter w języku Visual Basic jest niewrażliwa? Kiedy piszę ...

Dim ss As String
Dim SS As String

... do środowiska IDE programu Visual Studio 2008 lub Visual Studio 2010 , drugi zawiera ostrzeżenie „ Zmienna lokalna SSjest już zadeklarowana w bieżącym bloku ”. W VBA VBE nie powoduje natychmiastowego usunięcia błędu, ale po prostu automatycznie poprawia wielkość liter.

Czy brakuje mi czegoś z tym argumentem, że Visual Basic nie rozróżnia wielkości liter? (Ponadto, jeśli wiesz lub chcesz odpowiedzieć, dlaczego miałoby to być złe?)

Dlaczego w ogóle zadaję to pytanie?

Od lat używam języka Visual Basic w wielu jego dialektach, czasami jako hobbysta, a czasami w przypadku programów związanych z małym biznesem w grupie roboczej. Od sześciu miesięcy pracuję nad dużym projektem, znacznie większym, niż się spodziewałem. Znaczna część przykładowego kodu źródłowego jest w języku C #. Nie mam palącej ochoty na naukę języka C #, ale jeśli są rzeczy, których brakuje mi w tych ofertach C #, których nie oferuje Visual Basic (przeciwieństwem byłoby VB.NET oferuje Literały XML ), to chciałbym aby dowiedzieć się więcej o tej funkcji. W tym przypadku często twierdzi się, że w językach C rozróżniana jest wielkość liter i to dobrze, a Visual Basic nie rozróżnia wielkości liter, a to jest złe. Chciałbym wiedzieć...

  1. Jak dokładnie Visual Basic nie rozróżnia wielkości liter, skoro w każdym przykładzie w edytorze kodu jest rozróżniana wielkość liter (co oznacza, że ​​wielkość liter jest poprawiana), czy chcę, czy nie.
  2. Czy to wystarczająco przekonujące, żebym rozważał przejście do C #, jeśli przypadek VB.NET w jakiś sposób ogranicza to, co mogę zrobić z kodem?

5
+1 Już wcześniej zastanawiałem się nad tym samym.
NakedBrunch

7
Hmmm ... nie jestem pewien, że wiesz, co CASE- w drodze wrażliwych. Ponieważ VB w rzeczywistości nie rozróżnia wielkości liter, SS i ss mają tę samą nazwę, podczas gdy w C nie byłyby.
Ed S.,

1
@ed: Nie mogę używać obu SSiw ssVB, cokolwiek użyję jako pierwsze, jest używane przez redaktora.
Todd Main

1
Otaku, zdecydowanie zalecam skupienie się na tym pytaniu, co dokładnie oznacza, że ​​VB nie rozróżnia wielkości liter i jak jest zaimplementowany. Pytanie, czy lepiej, aby język nie rozróżniał wielkości liter, może niestety wywołać wojnę ognia. Jeśli jesteś naprawdę ciekawy, zadaj to w innym pytaniu. (Radzę ci tego nie robić, ale jeśli musisz następnie oznaczyć to subiektywnym i uczynić z niego wiki społeczności)
MarkJ,

16
Myślisz (lub myślałeś) o tym do góry nogami. Właśnie dlatego, że kompilator nie rozróżnia wielkości liter, błąd odczytuje „zmienną SS już zadeklarowaną”. Gdyby była rozróżniana wielkość liter, otrzymywałbyś albo „zmienną ss nieużywaną”, albo nie było żadnego błędu i błąd, jeśli używałbyś zamiennie jednej i drugiej.
Adriano Varoli Piazza

Odpowiedzi:


108

Różnica między VBA i VB.NET polega na tym, że VB.NET kompiluje się w tle. Podczas kompilacji VBA pojawi się błąd.

Jak mówi Jonathan , podczas programowania możesz myśleć o VB.NET jako o niewrażliwym na wielkość liter, poza porównaniami ciągów, XML i kilkoma innymi sytuacjami ...

Myślę, że interesuje cię to, co jest pod maską. Cóż, środowisko uruchomieniowe języka wspólnego .NET rozróżnia wielkość liter , a kod VB.NET opiera się na środowisku wykonawczym, więc widać, że w czasie wykonywania musi być rozróżniana wielkość liter, np. Podczas wyszukiwania zmiennych i metod.

Kompilator i edytor VB.NET pozwalają to zignorować - ponieważ poprawiają wielkość liter w kodzie.

Jeśli bawisz się funkcjami dynamicznymi lub późnym wiązaniem (opcja Strict Off), możesz udowodnić, że w bazowym czasie wykonywania rozróżniana jest wielkość liter. Innym sposobem, aby to zobaczyć, jest uświadomienie sobie, że języki z rozróżnianiem wielkości liter, takie jak C #, używają tego samego środowiska uruchomieniowego, więc środowisko uruchomieniowe oczywiście obsługuje rozróżnianie wielkości liter.

EDYCJA Jeśli chcesz usunąć IDE z równania, zawsze możesz skompilować z wiersza poleceń . Edycja kodu w Notatniku więc ma ssa SSi zobaczyć, co robi kompilator.

EDYTUJ Cytat z Jeffrey Richter w Wytycznych dotyczących projektowania .NET Framework, strona 45.

Aby było jasne, w CLR jest rozróżniana wielkość liter. W niektórych językach programowania, takich jak Visual Basic, wielkość liter nie jest rozróżniana. Gdy kompilator Visual Basic próbuje rozwiązać wywołanie metody do typu zdefiniowanego w języku z rozróżnianiem wielkości liter, takim jak C #, kompilator (nie CLR) wykrywa rzeczywisty przypadek nazwy metody i osadza ją w metadanych. CLR nic o tym nie wie. Teraz, jeśli używasz odbicia do powiązania z metodą, interfejsy API odbicia oferują możliwość wyszukiwania bez uwzględniania wielkości liter. Jest to zakres, w jakim CLR nie rozróżnia wielkości liter.


Najlepsza odpowiedź, jaką do tej pory słyszałem. Czy jest jakiś sposób, aby to udowodnić, że kompilator i edytor VB.Net pozwala to zignorować ? Czy jest sposób, aby jakoś wyłączyć automatyczną korektę? Czy istnieje sposób na skompilowanie sln, który nie jest napisany w VS IDE w programie MSBuild, który używa obu ssiSS będzie kompilować i działać zgodnie z oczekiwaniami?
Todd Main

5
Możesz wyłączyć automatyczną korektę, oszukując. Kliknij prawym przyciskiem myszy plik vb i wybierz „Otwórz za pomocą”. Następnie wybierz coś w rodzaju „Edytor XML (tekst)”. Utracisz wszystkie funkcje specyficzne dla VB, takie jak automatyczna korekta.
Jonathan Allen,

+1 świetna odpowiedź i dobre pytanie Otaku (myślę, że już wiedziałeś, ale chciałeś wyciągnąć dobrą definicję, hej?)
Anonimowy Wpisz

Kompilator / IDE VB.NET nie rozróżnia w 100% wielkości liter. Na przykład Dim pdfWriter As PDFWriterjest całkowicie ważny. VB.NET pozwala na rozróżnienie między nazwami klas i nazwami zmiennych, co jest miłym akcentem, ponieważ jest to powszechna praktyka w językach z pełną rozróżnianiem wielkości liter.
składnik_15939

Sposób VB jest odpowiedni dla interoperacyjności. Przykład: Utwórz bibliotekę DLL w C # z wiadomością e-mail jako ciągiem i Email () jako właściwością ze zdarzeniem inotifypropertychanged. C # skompiluje się dobrze i zostanie wygenerowana biblioteka DLL. Spróbuj odwołać się do tej biblioteki DLL w VB lub innym podobnym języku. Powie, że istnieje konflikt w zmiennej e-mail / e-mail w bibliotece. Narzędzia do analizy kodu wskazują to jako problem w kompilatorze C #, a nie w kompilatorze VB.
Venkat

22

Częściowo problem polega na tym, że musisz oddzielić język od środowiska IDE.

Jako język VB.NET z pewnością nie rozróżnia wielkości liter w odniesieniu do identyfikatorów. Dzwonię DateTime.Parseidatetime.parse będzie wiązać się z dokładnie tym samym kodem. W przeciwieństwie do języków takich jak C # nie można definiować metod lub typów różniących się tylko wielkością liter.

Jako IDE, VB.NET próbuje zachować wielkość liter istniejących identyfikatorów, podczas gdy ładnie wyświetla blok kodu. Ładne listy pojawiają się za każdym razem, gdy wychodzisz z bieżącej logicznej linii kodu. W tym przypadku opuszczasz drugą deklarację programu SS, ładny lister zauważa, że ​​istnieje identyfikator o tej nazwie i koryguje go, aby miał pasującą wielkość liter.

To zachowanie jest jednak wykonywane wyłącznie jako wartość dodana dla użytkownika. Nie jest częścią podstawowego języka.


1
Dzięki Jared, ciekawe, że to tylko IDE. Nadal nie rozumiem, dlaczego byłoby dobrze, gdyby więcej niż jedno imię reprezentowało różne rzeczy, tylko przez różnicę wielkości liter w nazwie, ale myślę, że to na inny dzień.
Todd Main

1
Nie sądzę, żeby Jared miał na myśli tylko IDE. Myślę, że on powiedział, że kompilator jest rozróżniana wielkość liter, więc uważa, ssjest identyczny SS, ale także jako pomoc w przeczytaniu koryguje IDE SSaby sspodczas pisania. Więc nawet jeśli IDE nie poprawi przypadku, kompilator nadal będzie widział te dwa identyfikatory jako identyczne.
MarkJ,

2
„Nadal nie rozumiem, dlaczego byłoby dobrze, gdyby więcej niż jedna nazwa reprezentowała różne rzeczy tylko przez różnicę wielkości liter w nazwie” <- Czułem to samo przed przejściem z VBA / VB6 / VB.NET na C # , Myślałem, że posiadanie nazw różniących się tylko przypadkami wydawało się po prostu niebezpieczne. W praktyce okazuje się jednak całkiem przydatny i, co zaskakujące, w ogóle nie jest podatny na błędy.
Mike Rosenblum

2
@Mike Bardzo się z tym nie zgadzam. Nigdy nie widziałem nazw mieszanych, które robią cokolwiek poza wprowadzaniem zamieszania.
JaredPar,

2
Naprawdę? Mam na myśli coś takiego jak void SetColor (kolor kolor) {this.color = kolor}; Zdaję sobie sprawę, że może to wyglądać niebezpiecznie, ale działa płynnie, kompilator nie pozwoli Ci popełnić błędu, a IntelliSense podaje poprawne elementy członkowskie po „kolorze”. kontra „Kolor”. Martwi mnie to, że użycie "this" nie jest wymagane - jest wymuszane przez FxCop i / lub StyleCop (nie pamiętam które), ale chciałbym, żeby było ustawienie, aby IDE zawsze wymuszało to podczas uzyskiwania dostępu do klasy członków zamiast potencjalnie pozwalać na przypadkowe przesłanianie zakresu.
Mike Rosenblum

16

VB w większości nie rozróżnia wielkości liter, ale są wyjątki. Na przykład w przypadku literałów XML i rozumienia rozróżniana jest wielkość liter. W porównaniach ciągów jest zwykle rozróżniana wielkość liter, w przeciwieństwie do powiedzmy T-SQL, ale istnieje przełącznik kompilatora, który sprawia, że ​​porównania ciągów nie uwzględniają wielkości liter. I oczywiście istnieją przypadki graniczne, jeśli chodzi o dziedziczenie, COM i Dynamic Language Runtime.


3
Dobre uwagi na temat tego, gdzie wielkość liter ma znaczenie, np. Literały XML i porównania ciągów. Ale kiedy mówimy, że jest to głównie niewrażliwe na wielkość liter, o czym dokładnie mówimy? Przechodząc do programu Outlook VBA, na przykład, jeśli wpiszę Dim mi as mailitemi subject = mi.subject, nazwy obiektów zostaną automatycznie poprawione do MailItemi mi.Subject. Czy kompilator przejmuje się tym (ponieważ zawsze to koryguje automatycznie), czy to ładny kod, czy ...?
Todd Main

1
Kompilator to nie obchodzi. Możesz to sprawdzić, edytując plik w notatniku i używając kompilatora wiersza poleceń.
Jonathan Allen

9

Tak, kompilator VB.NET traktuje identyfikatory w sposób niewrażliwy na wielkość liter. I tak, może to powodować problemy, gdy używa zestawów, które zostały napisane w innym języku lub używa składników COM. Ten pierwszy przypadek jest objęty specyfikacją języka wspólnego . Odpowiednia zasada brzmi:

Aby dwa identyfikatory można było uznać za różne, muszą różnić się czymś więcej niż tylko wielkością.

Przypadek COM jest dość prymitywnie obsługiwany przez konstruktora biblioteki typów, wymusza to identyczne wielkości liter identyfikatorów o tej samej nazwie. Nawet jeśli te identyfikatory mają różne role. Innymi słowy, parametr metody o nazwie „index” wymusi zmianę nazwy metody „Index” na „index”. To spowodowało dość dużo drapania po głowie, jak można sobie wyobrazić :)


6

VB zachowuje wielkość liter (w IDE), ale nie rozróżnia wielkości liter . To w pewnym sensie system plików Windows. Hello.txt i hello.txt są uważane za tę samą nazwę pliku.

IDE zakłada, że ​​deklaracja zmiennej jest „prawidłową” wielkością dla tej zmiennej i dostosowuje każde wystąpienie tej zmiennej do deklaracji. Robi to dla przyjemności dla oka i ze względu na spójność, ale nie ze względu na funkcjonalność.

Widziałem kilka przypadków, w których wielkość liter nie była automatycznie zmieniana w celu dopasowania do deklaracji, a instrukcja działa tak samo. Możesz także użyć dowolnego edytora tekstu, aby napisać kod, który będzie się dobrze kompilował w różnych przypadkach.

Na marginesie:

Większość LUDZI myśli bez rozróżniania wielkości liter. Kiedy widzimy słowo „pies”, w naszych umysłach zostaje ono przetłumaczone na znaczenie. Znaczenie tego słowa nie jest oparte na wielkości liter (tj. Niezależnie od tego, czy przeliteruje je „DOG”, „DoG” lub „dOG” nadal szczeka). KOMPUTERY widzą słowa jako dyskretne worki bitów. Wielkie i małe litery to różne wzory bitowe, a zatem są różne.

Ponieważ większość programistów to ludzie, niewrażliwość na wielkość liter wydaje się być bardziej dostosowana do sposobu, w jaki ludzie myślą, a wrażliwość na wielkość liter polega bardziej na tym, że ludzie dostosowują sposób myślenia do ograniczeń maszyny.


4
Tyle że programiści muszą rozróżniać obiekty i klasy i tradycyjnie używali do tego zmiany wielkości liter (nie jest to wymagane, tylko konwencja). Tak że object.method()i Object.Method()są natychmiast rozpoznawane jako obiektowych i klasowych i metod odniesienia (jeśli są zgodne z tym standardy kodowania). Podobnie jak w języku angielskim, nazwy własne i początki zdań rozróżnia się dużą literą. Więc podczas czytania lub programowania nie myślę bez rozróżniania wielkości liter, w przeciwnym razie straciłbym jakieś znaczenie.
Jason S

@Jason, chodzi o to, do czego jesteś przyzwyczajony. Nowi studenci programowania w C na początku zgłaszają niezliczone skargi dotyczące rozróżniania wielkości liter, a po kilku kursach przyzwyczajają się do tego. Object.method () i Object.Method () to tylko konwencja i najsilniejszy przypadek rozróżniania wielkości liter. Musiałem zmodyfikować program napisany przez kogoś innego, który miał dwie zmienne o nazwach temp i Temp w tym samym zakresie i powiem ci, że bardzo trudno było utrzymać je prosto w mojej głowie. I chociaż możemy rozpoznać rzeczownik pospolity wielkimi literami, słowa „bob” i „Bob” mają to samo znaczenie w naszych mózgach.
Andrew Neely,

Dlaczego w takim przypadku IDE zachowuje wielkość liter? (Przepraszam). Myślę, że IDE zachowuje przypadek, ponieważ projektanci MS uważają, że przypadek ma pewne znaczenie semantyczne w mózgu, co robi. Ale w rzeczywistości VB IDE uważa formi Formto samo, co i tak jest dla mnie mylące. W przypadku (przepraszam jeszcze raz) tempi Tempmożna łatwo użyć narzędzi refaktoryzacji w C #, aby zmienić nazwę Tempna bobTemplub cokolwiek. Jednak utrzymuję trochę VB i ktoś poszedł i zrobił Dim form As Form. Teraz, kiedy zmieniam nazwę, zmienia nazwy zarówno odwołań do klas, jak i obiektów. Bleah!
Jason S

@Jason, w VB zawsze mówię „Dim aform as Form”, ale dygresję. VB obsługuje rozróżnianie wielkości liter podczas wyszukiwania. Poza tym szukałbym „As Form” i zamieniłbym je na „coś głupiego”, potem zmieniłbym nazwę formy na sensowną, a następnie zmieniłbym nazwę „coś głupiego” z powrotem na „As Form”. Właściwie podoba mi się zmiana wielkości liter, ponieważ sprawdza, czy nie podałem nazwy zmiennej.
Andrew Neely,

Tak, ale to nie zastąpi narzędzia do refaktoryzacji, które rozróżnia odwołanie do klasy i instancji, gdy nazwy są takie same (lub różnią się tylko wielkością liter w VB). Wydaje się, że narzędzia do refaktoryzacji C # są w stanie to zrobić. Nie nazywam klas i instancji tak samo. W C # do rozróżnienia będę używał wielkości liter, ale w VB nie mogę tego zrobić, więc używam liter na początku. Oczywiście moim problemem jest to, że utrzymuję kod kogoś innego, kto używał tej samej nazwy. Ale ta dyskusja staje się zbyt obszerna, aby można było ją komentować, więc zostawię ją tutaj.
Jason S,

5

To jest część używanego edytora, mogą zachowywać się inaczej, ale faktem jest, że w Visual Basic naprawdę nie ma znaczenia wielkość liter. Więc ssi SSsą takie same.

Aby uzyskać więcej informacji, zapoznaj się z samouczkiem Podstawy VB.NET :)


och, to interesujące. czy jest jakieś miejsce, w którym sprawdzam ten szczegół? jeszcze nie testowałem, ale myśląc o VBScript, możesz mieć rację.
Todd Main

@Otaku: zobacz moją odpowiedź ponownie. Podałem teraz link. Dzięki
Sarfraz,

Jestem dość zaznajomiony z VB, dziękuję :) Nie jestem pewien, na co mam spojrzeć na tej stronie.
Todd Main

3

Nie jestem pewien, czy cię rozumiem? VB nie rozróżnia wielkości liter, więc ss i SS są tą samą zmienną, więc kompilator poprawnie zgłasza, że ​​zmienna została ponownie zadeklarowana.

Myślę, że zmienne nie uwzględniają wielkości liter, ale nazwy funkcji tak.


ale jeśli użyję, ssa później wpiszę SS, zostanie to automatycznie skorygowane do ss, co prowadzi do mnie, że kompilator rzeczywiście dba o wielkość liter.
Todd Main

5
@oTAKU: To IDE zmieniające wielkość liter, a nie kompilator.
John Saunders,

2
VB nadal nie dba o przypadek. IDE próbuje wyczyścić kod, aby zmienne pozostały niezmienione przez cały czas.
guitarthrower

1

Tak, VB nie rozróżnia wielkości liter. Czasami rzuca w pętlę tych, którzy nie są do tego przyzwyczajeni.


1

Nie trzeba się aż tak bardzo starać w VB.NET, aby stworzyć kod z różną pisownią identyfikatora, składającą się z wielkich / małych liter. Zmiana wielkości liter identyfikatora w pliku, w którym został zadeklarowany bez użycia funkcji „Rename”, nie spowoduje aktualizacji nazwy w innych plikach, natomiast edycja dowolnego wiersza zawierającego nazwę spowoduje, że będzie ona zgodna z aktualną definicją.

W ten sposób można stwierdzić, że VB.NET jest w większości niewrażliwa na wielkość liter, ale sprawia, że ​​CLR udostępnia identyfikatory wielkości liter, które mogą wykorzystywać te informacje w sposób uwzględniający wielkość liter.


1

Mogę tylko zaoferować to, co, jak pamiętam z moich podręczników programowania z wczesnych lat 80-tych, jest takie, że języki wrażliwe były (w tamtym czasie) ściśle przeznaczone do redukcji błędów czasu kompilacji. Oznacza to, że „ścisłość” miała na celu rozwinięcie dyscypliny kodowania o większej dokładności. Jak się okazało, ewoluowało również dodanie odpowiedniego etykietowania zmiennych, klas, metod, funkcji i wszystkiego, co chcesz tam dorzucić.

Pamiętam, że prawie wszystkie te książki zawierały zalecany wzorzec kapitalizacji, małych liter itp. Jak wszyscy wiemy, wiele z nich zostało wyrzuconych lub powinienem powiedzieć, zignorowanych w praktyce, z wyjątkiem domów produkcyjnych z wyższej półki, i Rozwiązania CASE lub dla tych, którzy osiągnęli wyższy poziom umiejętności. Myślę, że każdy doświadcza tej krzywej uczenia się.

Biorąc pod uwagę postęp w tych językach i IDE, lepszym pytaniem staje się, który język poprawia mój czas tworzenia? Oczywiście, jeśli nie znasz każdego z różnych języków, masz ograniczone możliwości.


1

Spróbuję odpowiedzieć na twoje drugie pytanie.

„Czy to wystarczająco przekonujące, żebym rozważał przejście na C #, jeśli przypadek VB.NET ogranicza w jakiś sposób to, co mogę zrobić z kodem?”

Utwórz usługę sieci Web WCF przy użyciu języka C #. Utwórz DataContract (1 klasa). Jeden z właściwością „string email”. Inny z „string Email” jako inną właściwością. Twój wybór, aby rozumieć jako osobisty e-mail lub e-mail w biurze. Lub może być w dwóch różnych DataContracts.

W przypadku C # jest to w porządku. Usługa internetowa została utworzona w porządku. Program AC # może łatwo utworzyć WSDL i wszystko jest w porządku.

Teraz spróbuj utworzyć WSDL z VB (dowolna wersja). Powie "email" jest już zadeklarowany i generowanie WSDL nie powiedzie się.

Jak wszyscy, założyłem, że jest to wada języka VB. Ale!!!

Użyj FxCOP i przeanalizuj oryginalny kod C #. FxCOP mówi, że używanie poczty elektronicznej / poczty elektronicznej jest problemem. Zaleca użycie innej nazwy wspierającej niewrażliwość na wielkość liter. Należy również zauważyć, że na dzień dzisiejszy .NET Framework ma 106 języków programowania, a wiele języków ma włączoną rozróżnianie wielkości liter. Wszyscy zmierzamy w kierunku chmury i chcemy, aby nasze usługi były dostępne dla wszystkich platform programistycznych / języków.

Tak więc uwzględnianie wielkości liter jest twoim wyborem w programie, a jeśli jesteś facetem C, chciałbyś tego. Jeśli program ma być używany / otwierany przez inne programy inne niż C, musisz uwzględnić niewrażliwość na wielkość liter, ale Twój język jest Twoim wyborem.

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


Chmura używa identyfikatorów URI, w których rozróżniana jest wielkość liter (co jest szczególnie ważne w przypadku serwerów proxy i serwerów pamięci podręcznej).
binki

1

Ukrywanie symboli (np. Lokalne pole ukrywania) jest również niewrażliwe na wielkość liter.

Oto przykład :

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

Dane wyjściowe kompilatora VB.NET są dekompilowane do (a zatem równoważne) z następującym C #:

public class C
{
    public string Name;

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

string.Equalsdwukrotnie przechodzi przez to pole. Lokalny jest ukryty, niezależnie od przypadku. W języku nie jest rozróżniana wielkość liter.

Aby jawnie odwołać się do członka, takiego jak to pole, należy usunąć odwołanie do członka za pomocą Me:

Return String.Equals(name, Me.Name) ' differentiate field from local

0

Nie widziałem nikogo, kto skomentuje twoje wyraźne drugie pytanie na końcu: „2: czy jest to wystarczająco przekonujące, bym rozważał przejście na C #, jeśli przypadek VB.NET ogranicza w jakiś sposób to, co mogę zrobić z kodem?”

Wolę podejście oparte na większej liczbie opcji, ponieważ C # pozwala programiście zdecydować, czy niż ograniczanie opcji programisty. Zdecydowanie wolę C #, ale ze względu na wielkość liter nie myślę nawet, że jest blisko nauki języka tylko dlatego, że rozróżnia wielkość liter. wszystkie funkcje mają znaczenie, a kiedy patrzę na zalety obu języków C # i VB.NET, bardzo wolę C #. ale dam ci prawdziwie zrównoważoną perspektywę, stronniczą tak, ponieważ mam preferencje, ale będę też szczery co do wad języka C #.

po pierwsze, oba języki mają zalety i wady. różnice, które można zrobić w jednym języku, których nie można zrobić w drugim, maleją, ponieważ na szczęście Microsoft ulepsza oba języki i wydaje się, że nie wykazują niesprawiedliwej stronniczości w stosunku do żadnego z nich.

kiedy C # pojawił się po raz pierwszy, VB nie miał swoich komentarzy XML, które można by umieścić przed metodami, które uwielbiałem w C #. Nienawidziłem tego w VB.NET. ale widziałem przez lata, że ​​wiele funkcji, które nie są w jednym języku, zostało dodanych do drugiego. (ten sam zespół programistów MS opracowuje zarówno C #, jak i VB, więc ma sens, aby funkcje stały się dość podobne.)

ale zapytałeś, co ma C #, czego VB nie ma. oto kilka, które przychodzą mi do głowy od razu:

1: C # jest bardziej zwięzły i wymaga mniej pisania ... na WIELE sposobów! Widziałem nawet głupotę mówiącą, gdy jest przeciwne twierdzenie, że VB oszczędza pisania. ale proszę, słuchaj ludzi, którzy mówią ci, że używają obu języków i żaden z nich nie jest przez nich rzadko używany. używam zarówno C # iVB, C # w domu, ponieważ mi się podoba (i kiedy pracuję z C # w pracy), oraz moje nowsze prośby o pracę, w których używam VB, a nie C #. więc teraz coraz częściej używam VB (od około 10 miesięcy), ale w moim osobistym świadectwie zdecydowanie wolę C #, a jeśli chodzi o rzeczywiste pisanie, VB jest znacznie bardziej typowym. jeden przykład, który przeczytałem, gdzie ktoś faktycznie próbował powiedzieć VB był bardziej zwięzły, podał przykład „with…” z długą zmienną w with, więc w VB możesz po prostu użyć „.property”. to jest głupota w twierdzeniu, że VB wymaga mniej pisania. jest kilka rzeczy (i nie tylko w tym przykładzie), w których język VB jest krótszy, ale w praktyce znacznie częściej, gdy C # jest bardziej zwięzły.

ale największym powodem, dla którego uważam, że C # jest bardziej zwięzły, są szczegółowe instrukcje VB „IF / THEN”. jeśli stwierdzenia są wspólne. w C # nie ma słowa „to” do wpisania! :) również wszystkie instrukcje „end ...” wymagają wpisania, co w języku c # jest zwykle tylko jednym nawiasem zamykającym „}”. Czytałem, że niektórzy twierdzą, że ta większa rozwlekłość w VB.NET jest zaletą VB, ponieważ kilka zamykających instrukcji blokowych / symboli może być zagnieżdżonych i kończyć się bezpośrednio obok siebie, ale zupełnie się z tym nie zgadzam. prawie zawsze można napisać program lepiej w języku C # lub VB niż inny programista, ponieważ następna wersja kodu mogłaby być lepiej zaprojektowana. dotyczy to „mylących wielu nawiasów zamykających w C #” oraz jeśli zagnieżdżone bloki są tego samego typu, co kilka zagnieżdżonych IF, wówczas VB ma ten sam problem, co w C #. nie jest to korzystne w VB. Właśnie ta sytuacja jest powodem, dla którego lubię komentować, co oznacza mój symbol zamknięcia lub stwierdzenie końcowe w obu językach. tak, jest to bardziej rozwlekłe, ale w każdym języku możesz wyrazić się jasno, co jest ważne w przypadku konkretnych sytuacji opartych na osądzie. myślę, że przejrzystość kodu jest dość ważna.

2: VB nie ma komentarzy wieloliniowych. kiedy pracowałem z VB, nie przeszkadzało mi to. potem przeszedłem do kilku języków w stylu C. teraz wróciłem głównie do korzystania z VB.NET w pracy i tęsknię za nimi. to po prostu coś, co uważasz za wygodne, a potem musisz stracić. :(

3: „andalso” i „orelse” w języku VB jest raczej irytujące, gdy wpisuje się to wszystko w C # to po prostu „&&” i „||”. znowu mniej pisania. nie jest to rzadkie w moim kodzie zarówno w języku VB, jak i C #. jeśli cokolwiek, ze względu na funkcjonalność, „OR” kontra „OrElse” zwykle nie ma znaczenia, z wyjątkiem tego, że „OrElse” jest szybsze dla komputera, więc jeśli programista używa po prostu „Or” i „And” w VB, to tworzy mniej optymalny kod dla ktoś, kto lubi przejrzystość kodu. „Or” jest o wiele łatwiejsze do przejrzenia niż „OrElse”.

4: większa elastyczność w umieszczaniu kodu w C #. kiedy linia jest długa i chcesz ją zawinąć w następną, nienawidzę „kontrolowania” przez VB.NET ponownej regulacji mojego kodu. C # robi to trochę, ale uważam, że jest bardziej przydatny w C #, podczas gdy w VB jest znacznie bardziej kontrolujący. ale jest to bardziej VB.NET IDE vs C # IDE, a nie sam język. ale nie wiem, czy chcesz mieć obie, czy tylko funkcje językowe bez różnic IDE.

5: jedyną rzeczą, za którą naprawdę tęsknię, jest po prostu utworzenie nowego bloku kodu w C #, w metodzie może wiele się dziać i chcę zadeklarować zmienną w bardzo małym bloku kodu, ale nie zadeklarować tej zmiennej poza tym blokiem w całą metodę. w C # możemy po prostu utworzyć nowy blok za pomocą „{” i zakończyć go „}”. VB nie ma takiej funkcji, ale najbliższym dopasowaniem jest bezwarunkowy blok „Jeśli prawda to” i „Zakończ, jeśli”. (zwróć uwagę na 2-znakowy odpowiednik C # w porównaniu z 18-znakowym odpowiednikiem VB.NET ... więcej pisania w VB.)

6: operatory samoinkrementacji i dekrementacji: ++ i - jak w myVariable++lub ++myVariablelub równoważne wersje dekrementacji. jest to bardzo przydatne ... czasami. oto przykład rzeczywistego kodu, kiedy bardzo brakowało mi 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

I żeby dać BARDZO dobry przykład, gdzie reguły C #, oto więcej kodu, który osobiście ostatnio napisałem:

// 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

Być może jest to wystarczający dowód, że C # jest bardziej zwięzły. Ale nie wszyscy programiści lubią zwięzłość. Niektórzy wolą czytać „if a <b then…”, ponieważ jest to bardziej naturalne dla ich ludzkiego języka. I to jest w porządku. Preferencje są w porządku. Dla mnie wysiłek rąk jest wartością i i myślę, że każdy może przyzwyczaić się do myślenia dowolnymi symbolami, ponieważ „jeśli” i „to” są symbolami alfabetu, a instrukcja „if (warunek)” w języku C #; składnia to też symbole. jeden jest po prostu bliższy składni nieprogramisty niż drugi. wolę zwięzły.

Myślę też, że potrzeba użycia „c” po literałach znakowych w VB, aby uczynić go literałem znakowym, a nie ciągiem, jest denerwująca. O wiele bardziej podoba mi się zwięzłość języka C #. gdy metoda wymaga literału znakowego, musisz podać znak, a nie ciąg o jednej długości znaku, więc czasami musisz użyć ":"cw języku VB, podczas gdy w C # tak jest ':'. Myślę, że to jest jednak chwytanie nitów.

Aby być sprawiedliwym, muszę powiedzieć, istnieją zalety lubię VB jak nie trzeba stawiać pustych nawiasów po wywołań metod, jak Dim nameUpper$ = name.ToUpperInvariantgdzie C # wymaga pustych nawiasów: string nameUpper = name.ToUpperInvariant(). lub podwoić że jak przycinanie go zbyt: Dim nameUpper$ = name.Trim.ToUpperInvariantvs string nameUpper = name.Trim().ToUpperInvariant(). Podoba mi się zwięzłe użycie VB tego, jak właśnie użyłem$ powyżej, aby przyciemnić to `` As String '', gdzie C # nie ma tych skrótów. VB ma te skróty dla typów String, Integer, Long, Decimal, Single i Double, ale wadą jest to, że jest mniej jasny, więc używam go ostrożnie. niemniej jednak wolę zwięzły kod.

Cóż, to tylko kilka dziwek od tego doświadczonego programisty i jak uważam, to jest moje „świadectwo” programowania C # vs VB. moim zdaniem oba są fajnymi językami. ale tak, nadal wolę C #.

ps Ponieważ planuję programować przez większość swojego życia, nawet ponownie nauczyłem się pisać przy użyciu najbardziej wydajnej klawiatury: klawiatury Dvorak, której pisanie po angielsku zajmuje około 1/3 wysiłku niż na klawiaturze Qwerty. sprawdź to. może też zechcesz się przełączyć. ;) Ułatwiło mi to pisanie o 67%! :) Zachęcam każdego do nieszablonowego myślenia i oceny lepszej efektywności pracy. Uproszczony układ klawiatury Dvoraka i C # zrobiły to za mnie. :)

PSS porównałbym Dvorak i C # do metryki, w przeciwieństwie do układu klawiatury Qwerty i VB do pomiarów Empirial. Dvorak, metric i C # są po prostu „czyste”. ALE VB nie jest daleko w tyle. Ale cierpi z powodu konieczności zachowania kompatybilności wstecznej ze starym kodem VB6 i kodem pre .NET, takim jak „Or” vs „OrElse” i „IIF ()”.

Kończę ostrożnie. Prosimy, bądź ostrożniejszy niż słuchanie ludzi, którzy tak naprawdę nie wiedzą, o czym mówią. Połowa wszystkich wad przeciwko VB i C # to nie jestjakikolwiek problem, a ludzie wciąż piszą, że nie wiedzą, jakie wady naprawdę nadal istnieją w języku. Najlepszym przykładem, jaki przychodzi mi do głowy, są komentarze XML dla metod wykorzystujących potrójny apostrof w VB lub symbole komentarzy z potrójnym ukośnikiem w C #. Ale proszę, zastanów się, czy dana osoba mówi z powodu ignorancji, czy z doświadczenia. Osobiste świadectwo oznacza, że ​​wiedzą z prawdziwego doświadczenia. A kiedy ktoś ma w tym duże doświadczenie, nadstaw uszy. Mam ponad 10 lat doświadczenia w językach C # i VB. Sprowadza się to do tego: oba są (bardzo) dobrymi językami. Większość różnic widać od razu w ciągu 5 minut od przeczytania kodu. Ale tak, w przypadku innych funkcji znalezienie upośledzenia może zająć lata. I jeden handicap, którego jestem świadomy (w C #), mogę ” Nie myśl nawet o prawdziwej sytuacji życiowej, w której byłoby to przydatne. Więc może w końcu to nie jest przeszkoda.

Miłego kodowania!


Doceniam wszystkie szczegóły, ale Twój przykład nie uwzględnia wielkości liter / niewrażliwości (o ile mogłem powiedzieć), aby pokazać, dlaczego C # jest w jakiś sposób „lepszy”.
Todd Main

Na drugie pytanie starałem się odpowiedzieć bezpośrednim przykładem.
Venkat

@ToddMain, dobrze. W moim przykładzie nie uwzględniono wielkości liter, aby pokazać, dlaczego język C # jest lepszy, ponieważ pytanie nie zawiera pytania, dlaczego uwzględnianie wielkości liter sprawia, że ​​jest lepsza. Poza tym uważam, że ta funkcja mówi sama za siebie. Uważam, że logika jest podstawową zasadą, że większość ludzi może samodzielnie to wydedukować. Ale jeśli ktoś zapyta, z przyjemnością pomogę mu przejść przez logikę. Ale to, mój przyjacielu, moim zdaniem, jest inna kwestia. ;)
Shawn Kovac

Właściwie to było jedno z dwóch pytań zadanych w oryginalnym poście. Nie jest to oczywiste, dlatego zapytałem. Ale nie martw się, że nie odpowiesz na to pytanie.
Todd Main,

@ToddMain, rozumiem twój punkt widzenia. rzeczywiście bardzo słuszna uwaga. :) Dziękuję za otworzenie mi oczu. :)
Shawn Kovac

0

VB.NET rozróżnia wielkość liter.

Przykłady:

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

Wszystkie te kody spowodują BŁĄD CZASU KOMPILACJI .

W pierwszym przykładzie zostanie wyświetlony błąd, mówiący: „Zmienna lokalna 'A' jest już zadeklarowana w bieżącym bloku.”.

Podczas gdy w przypadku drugiego i trzeciego przykładu zostanie wyświetlony błąd informujący, że „Public Sub b ()” ma wiele definicji z identycznymi podpisami. oraz „Funkcja publiczna c () As Integer” ma wiele definicji z identycznymi podpisami. ”.

Z tych błędów zwróć uwagę, że są one wyrzucane w różnych pozycjach dla zmiennych i procedur / funkcji. W przypadku zmiennych błąd jest zgłaszany w drugiej deklaracji, natomiast w przypadku procedur / funkcji w pierwszej deklaracji / definicji identycznego kodu.

Jak powiedział użytkownik w komentarzu gdzieś powyżej, kod VB.NET jest stale sprawdzany i / lub poprawiany w tle; można zobaczyć ten błąd w oknie „Lista błędów” w VS IDE. A ponieważ jest to BŁĄD, a NIE OSTRZEŻENIE , kod nie zostanie skompilowany, dopóki błąd nie zostanie rozwiązany.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.