Преобразование знаний C# в VB.NET есть потенциальные проблемы?

У меня есть команда с людьми, которые чувствуют себя достаточно комфортно в C#, но у нас есть требование написать проект на VB.net. Насколько сложно было бы думать на C# и на лету конвертировать в VB? Это выполнимо?

Не могли бы вы перечислить проблемы, с которыми мы можем столкнуться?

Я слышал, что у VB.net нет закрытий. Это все еще верно для.net 3.5?

13 ответов

Решение

Если вы приближаетесь к VB.Net с мышлением C#, лучше всего установить следующие параметры в проекте

  • Вариант Строгое Вкл
  • Опция Явный Вкл
  • Опция Infer On

Это по существу удаляет семантику позднего связывания VB.Net и заставляет его быть строго типизированным языком. Это приблизит его к семантическому смыслу C# (но все же не совсем точно).

VB.Net имеет поддержку лямбда-выражений (и, следовательно, Closure), начиная с выпуска Visual Studio 2008 / .Net Framework 3.5. Не выражение и не утверждение. Лямбды операторов не поддерживаются до VS2010 / .Net Framework 4.0. Хотя вы можете использовать 4.0 компилятор, чтобы снизить 2.0 фреймворки.

Поскольку C# и VB.NET используют одну и ту же инфраструктуру и компилируют очень похожий IL-код, у вас есть много бесплатного. Написание базового синтаксиса не так сложно.

Синтаксис C# больше нацелен на то, чтобы показать, что происходит, в то время как синтаксис VB часто скрывает некоторые детали, поэтому программист C# уже знаком с некоторыми понятиями, которые могут вообще не быть очевидными для программиста VB. В некотором смысле изучение C# - лучший способ узнать, как работает VB, чем изучение самого VB...

Я часто отвечаю на вопросы VB.NET на разных форумах, в основном основываясь на моих знаниях C#, и я до сих пор не написал ничего, кроме коротких тестовых программ на VB.NET.

Есть, конечно, некоторые причуды, на которые нужно обратить внимание в VB. Как, например, оператор /, который всегда преобразует оба операнда в двойной, или операнд =, который использует специальный код сравнения VB, а не сравнение, указанное для оператора равенства в классах.NET.

Одна из областей, которую VB.NET стремится скрыть, - это работа с событиями; другие кратко коснулись некоторых различий, но вот еще немного о них:

VB.NET предоставляет WithEvents ключевое слово для полей, которые вызывают события. Если поле объявлено WithEvents тогда вы можете добавить Handles field.Event до конца метода, чья подпись совместима с событием; этот метод автоматически будет делегатом события без необходимости вручную AddHandler а также RemoveHandler (+= а также -=).

Private WithEvents SomeField
Public Sub SomeField_SomeEvent(sender as Object, e as EventArgs) Handles SomeField.SomeEvent
    Console.Writeline("SomeEvent occured")
End Sub

Объявления о событиях и их поднятия немного упрощены. VB.NET не требует, чтобы вы проверяли, является ли событие нулевым, до уведомления слушателей:

Public event SomeEvent as EventHandler(of SomeEventArg)
Public Sub SomeMethod()
    RaiseEvent SomeEvent(Me, new EventArgs)
End Sub

Одна "скрытая" особенность событий в VB.NET - доступ к базовым MulticastDelegate, чтобы сделать что-то вроде GetInvocationList() Примечание: событие называется SomeEvent и код для доступа к многоадресной передаче вызывает невидимое поле с именем SomeEventEvent:

Public event SomeEvent as EventHandler(of SomeEventArg)
Public Sub SomeMethod()
    // Note that SomeEvent's MulticastDelegate is accessed by appending
    // another "Event" to the end, this sample is redundant but accurate.
    // If the event was named ListChanged then it would be ListChangedEvent
    dim invocationList = SomeEventEvent.GetInvocationList()
End Sub

В январе 2008 года в журнале Visual Studio было несколько полезных статей.

Вас также может заинтересовать вопрос " что разрешено в VB, что запрещено в C# (или наоборот)"

Точка, которая здесь не упоминалась, состоит в том, что инициализаторы полей в C# выполняются перед базовым конструктором, тогда как инициализаторы в VB выполняются между базовым конструктором и первым "реальным" оператором конструктора производного класса (после вызова базового конструктора)., если таковые имеются). Это позволяет инициализаторам поля в производном классе использовать членов базового класса (которые могли быть инициализированы с использованием параметров, переданных в конструктор), но также означает, что если конструктор базового класса объекта проходит сам где-то раньше возвращается, частично созданный объект может быть использован до того, как все инициализаторы поля запустятся. В C# все инициализаторы полей будут выполняться до того, как базовый конструктор начнет выполнение, но ни один из инициализаторов полей не сможет использовать частично созданный объект.

PS - если кто-нибудь из Microsoft, стоящий за C#, прочтет это, возникнет ли какая-то особая трудность при добавлении контекстно-зависимого ключевого слова для объявлений полей, чтобы указать, должны ли они обрабатываться до или после базового конструктора, или, возможно, их выполнит какой-то специальный метод, который может быть вызван из конструктора, который может быть обернут в блок try-finally (чтобы любые выделенные таким образом IDisposables могли быть очищены) и мог бы также использовать параметры, передаваемые конструктору?

Одна из самых больших проблем, которые я обнаружил, - очевидное многословие VB. У него есть все эти большие ключевые слова, такие как MustInherit, NotInheritable, MustOverride и т. д., где C# просто имеет такие вещи, как sealed, abstract а также virtual, Вы должны иметь End ко всему (End Sub, End Function, End While, End Namespace, End Class и т. д.) И вы должны явно пометить свойства только для чтения с помощью ReadOnly ключевое слово; простое опускание сеттера не сработает. Также помня AndAlso а также OrElse вместо более интуитивного (но не короткого замыкания) And а также Or и тому подобное Is Nothing а также IsNot Nothing вместо == null или же != null,

Ни одна из этих проблем не обязательно является проблемой с языком, но если вы привыкли к относительной простоте C#, код VB может показаться вам лишним.

Как и любой язык (человеческий или компьютерный), вы сначала учитесь "переводить в своей голове", а затем начинаете "думать" на другом языке.

Чем быстрее ваша команда сможет совершить этот прыжок, тем лучше. Итак, сделайте это так же, как эксперты говорят вам, чтобы выучить человеческий язык: реальные примеры и погружение.

В Интернете есть несколько утилит для преобразования C# в VB.NET, поэтому начните с того, что команда напишет на C#, преобразует в VB.NET и очистит его. (Утилиты преобразования различаются по качеству и имеют некоторые ограничения, особенно с использованием новых языковых функций.)

Как только они освоят базовую "грамматику", поместите их на VB.NET на 100%.

Я использую их каждый день, часто в разных окнах кода одновременно, и у меня нет проблем с переключением контекста или выполнением "правильных действий" в каждом из них.

Я считаю, что это удобная статья, освещающая различия. Я программист на vb.net, и это помогает мне понять код на C#, так что я уверен, что он будет работать по-другому!

http://www.codeproject.com/KB/dotnet/vbnet_c__difference.aspx

Принимая во внимание возраст этого вопроса, этот вопрос, вероятно, сейчас довольно хорошо известен, но я добавлю одну большую ошибку, которую я видел с точки зрения написания VB.NET, как пользователь C#:

Nothing не означает null, это означает default(T)

Это значит, что...

Dim a As Integer = Nothing
Dim b As Integer? = Nothing 

... полностью действителен и фактически означает...

int a = default(int);    // 0
int? b = default(int?);  // null

Ответ Джона М. Ганта касается того факта, что есть специальные ключевые слова для сравнения сNothing-смысл-null - Is Nothing а также IsNot Nothing но, если вы забудете и воспользуетесь =, вы можете получить неожиданный результат, который трудно отследить:

Dim a As Integer? = Nothing
If a = Nothing Then Console.WriteLine("a = Nothing")
If a <> Nothing Then Console.WriteLine("a <> Nothing")
If a Is Nothing Then Console.WriteLine("a Is Nothing")
If a IsNot Nothing Then Console.WriteLine("a IsNot Nothing")

'Output:
'a Is Nothing

Это, по крайней мере, улавливается предупреждениями компилятора (BC42037 и BC42038), поэтому вы можете заставить эти предупреждения быть ошибками в вашем файле VBPROJ.

Помимо того, что Джаред уже упоминал, у вас не должно быть проблем с этим. Единственный источник раздражения - странные настройки по умолчанию. EG Знаете ли вы, что проекты VB.NET по умолчанию скрывают узел ссылок в обозревателе решений? (Вы должны выбрать ShowAllFiles, чтобы увидеть его).

Я не думаю, что это будет слишком сложно. VB.NET и C# являются языками, которые близки друг к другу, только синтаксис действительно отличается. Конечно, вашей команде понадобится некоторое время, чтобы привыкнуть к новому языку, но я не думаю, что вы столкнетесь с большими проблемами.

Да, и у VB.NET есть замыкания. В C# отсутствуют некоторые другие функции, такие как ключевое слово yield, лямбда-выражения нескольких операторов и автоматические свойства, но ничего особо важного.

Один из вариантов, если вам не хочется писать код vb.net, - это написать свой проект на C#, скомпилировать его и использовать Reflector, чтобы увидеть, как выглядит эквивалент vb.net. В любом случае все сводится к MSIL!

Есть некоторые тонкие различия, на которые вам следует обратить внимание. Например, VB.Net не имеет понятия короткого замыкания в операторе if (я был исправлен, по-видимому, так и есть). Если это всего лишь краткосрочный проект, у вас, вероятно, не будет проблем, но разные языки имеют разные подходы к решению одной и той же проблемы. Примером этого являются программисты на Python, говорящие о том, чтобы делать что-то "питоническим" образом. Об этой концепции они рассказывают в книге "Мечты в коде", где программисты Java пытались программировать Java с использованием синтаксиса Python. Это приводит к долгому пути к решению проблемы. Произойдет ли это с C# и VB.Net? Трудно сказать, они оба используют базовую структуру фрейма, поэтому различия не будут огромными, но это все равно поможет попытаться узнать, как использовать VB.NET так, как это было задумано.

Редактировать: так, очевидно, у него есть концепция короткого замыкания, но он не делает это по умолчанию, где C# делает. Это еще раз доказывает, что изучение языка может быть полезным в долгосрочной перспективе.

Я думаю, что C# для VB.NET не будет слишком болезненным, это всего лишь случай изучения нового синтаксиса. В текущих версиях возможности обоих языков довольно тесно связаны.

Обратный путь (от VB.NET к C#) может быть сложнее, потому что люди могут привыкнуть использовать пространство имен "Мой" и другие вещи, добавленные туда, чтобы разработчики VB6 чувствовали себя как дома.

Другие вопросы по тегам