Что разрешено в Visual Basic, которое запрещено в С# (или наоборот)?

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

Просьба представить пример кода с вашим ответом, если это возможно. Спасибо!

Ответ 1

VB и С# имеют разные интерпретации того, что означает "защищенный".

Здесь объяснение скопировано ниже:

Конструктор по умолчанию для WebControl защищен.

VB и С# имеют разные интерпретации того, что "защищено" означает.

В VB вы можете получить доступ к защищенному член класса из любого метода в любой тип, который выводится из класса.

То есть, VB позволяет этому коду компиляции:

class Base
    protected m_x as integer
end class

class Derived1
    inherits Base
    public sub Foo(other as Base)
        other.m_x = 2
    end sub
end class

class Derived2
    inherits Base
end class

Поскольку "Derived1" является базой, он может доступ к защищенным членам "другого", который также является базой.

С# использует другую точку зрения. Это не разрешает доступ "вбок" что делает VB. В нем говорится, что доступ к защищенные члены могут быть сделаны через "this" или любой объект того же типа как класс, содержащий этот метод.

Поскольку "Foo" здесь определяется в "Derived1", С# разрешает только "Foo", для доступа к элементам "Base" из Экземпляр "Derived1". Это возможно для "другое" - это нечто, что не является "Derived1" (может быть, например, "Derived2" ), и поэтому он не разрешить доступ к "m_x".

Ответ 2

VB.NET поддерживает CIL Exception Filters, С# не поддерживает:

Try 
  ...
Catch ex As SomeException When ex.SomeProperty = 1
  ...
End Try 

Ответ 4

Компилятор VB 9.0 автоматически переводит литерал XML в синтаксис "функционального построения". Компилятор С# не поддерживает этот хороший XML-синтаксис.

Ответ 5

Обрабатывает и WithEvents ключевые слова для автоматической проводки EventHandlers.

Private Sub btnOKClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOK.Click
End Sub

Ответ 6

В VB вы можете реализовать интерфейс с помощью метода любого имени - то есть метод "Class.A" может реализовать интерфейсный метод "Interface.B".

В С# вам нужно будет ввести дополнительный уровень косвенности для достижения этой цели - явную реализацию интерфейса, которая вызывает "Class.A" .

Это в основном заметно, если вы хотите, чтобы "Class.A" был protected и/или virtual (явные реализации интерфейса не являются ни тем, ни другими); если бы это было просто "private", вы, вероятно, просто оставите его как явную реализацию интерфейса.

С#:

interface IFoo {
    void B();
}
class Foo : IFoo { 
    void IFoo.B() {A();} // <====  extra method here
    protected virtual void A() {}
}

VB:

Interface IFoo
    Sub B()
End Interface
Class Foo
    Implements IFoo
    Protected Overridable Sub A() Implements IFoo.B
    End Sub
End Class

В IL, VB делает это сопоставление напрямую (это хорошо, нет необходимости, чтобы метод реализации имел общее имя).

Ответ 7

VB допускает не виртуальные вызовы для методов виртуальных экземпляров (call в IL), тогда как С# разрешает только виртуальные вызовы (callvirt в IL). Рассмотрим следующий код:

Class Base
    Public Overridable Sub Foo()
        Console.WriteLine("Base")
    End Sub

    Public Sub InvokeFoo()
        Me.Foo()
        MyClass.Foo()
    End Sub
End Class

Class Derived : Inherits Base
    Public Overrides Sub Foo()
        Console.WriteLine("Derived")
    End Sub
End Class

Dim d As Base = New Derived()
d.InvokeFoo()

Вывод:

Derived
Base

Это невозможно в С# (не прибегая к Reflection.Emit).

Ответ 9

Сверху моей головы (до 4.0):

Функции языка VB "не поддерживаются в С#:

  • Дополнительные параметры
  • Поздняя привязка
  • Нечувствительность к делу

Я уверен, что там больше. На ваш вопрос могут возникнуть лучшие ответы, если вы попросите конкретные примеры того, где каждый язык отличается. VB в настоящее время лучше, чем С# при взаимодействии с COM. Это связано с тем, что COM гораздо меньше болит, когда доступны дополнительные параметры, и когда вам не нужно связываться с (часто неизвестным типом) во время компиляции.

С#, с другой стороны, предпочтительнее многих при написании сложной логики из-за безопасности своего типа (в том, что вы не можете обойти статическую типизацию) и ее краткости.

В конце концов, языки в основном эквивалентны, поскольку они только различаются по краям. Функционально они одинаково способны.

ИЗМЕНИТЬ

Чтобы быть ясным, я не подразумеваю, что VB не допускает статического ввода текста... просто, что С# еще не позволяет обойти статическую типизацию. Это делает С# более привлекательным кандидатом для определенных типов архитектур. В спецификации языка 4.0 С# вы можете обойти статическую типизацию, но вы делаете это, определяя блок динамического кода, а не объявляя весь файл "не строгим", что делает его более преднамеренным и целенаправленным.

Ответ 10

Индексированные свойства разрешены в VB.NET, но не в С#

    Private m_MyItems As New Collection(Of String)
    Public Property MyItems(ByVal index As Integer) As String
        Get
            Return m_MyItems.Item(index)
        End Get
        Set(ByVal value As String)
            m_MyItems.Item(index) = value
        End Set
    End Property

Ответ 11

В С# вы можете объявить свойство в интерфейсе как имеющее "get", а затем реализовать его в классе с get и set.

public interface IFoo {
  string Bar {get;}
}

public class Foo : IFoo {
  public string Bar {get; set;}
}

В VB эквивалент объявления свойства с помощью get будет объявлять его ReadOnly. Вы не можете сделать реализацию доступной для записи.

Public Interface IFoo 

  ReadOnly Property Bar() As String

End Interface

Public Class Foo 
   Implements IFoo

  Public Property Bar() As String Implements IFoo.Bar  'Compile error here'

End Class

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

Ответ 12

Одна из пропущенных или просто неправильно понятых особенностей языка VB вызывает функцию, которая имеет параметр ByRef. Большинство языков поддерживают только один метод передачи параметров по ссылке: это сценарии, напрямую поддерживаемые CLR.

CLR имеет множество ограничений на тип значений, которые он поддерживает для параметров ByRef, и эти ограничения мешают цели VBs быть гибким языком. Следовательно, компилятор идет на большие длины, чтобы быть гибким и поддерживать несколько путей прохождения ByRef, намного дальше, что позволяет CLR.

С# 4 теперь поддерживает две версии передачи ссылок. В дополнение к той, которая доступна с версии 1.0, модификатор ref теперь является необязательным при выполнении вызова interop для COM-объекта.

Ответ 13

VB имеет необязательные параметры для функций.

С# будут получать только С# 4.0

Ответ 14

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

Ответ 15

Новые автопрограммы в С# еще не были выполнены для VB.NET.

Ответ 17

Один из моих фаворитов (и обломки)

В VB.Net вы можете навязать оператор switch/case как таковой:

Select Case True

   Case User.Name = "Joe" And User.Role = "BigWig" And SecretTime = "HackerTime"
      GrantCredentials()

End Select

который позволяет вам оценивать некоторые сложные оценки с помощью коммутатора вместо множества блоков if/else. Вы не можете сделать это на С#.

Ответ 18

В С# вы должны назначить свою переменную, прежде чем сможете ее использовать. Я думаю, вы можете отключить это, но это поведение по умолчанию.

Так что-то вроде этого:

int something;
if (something == 10)
{ ... }

Не разрешено, но эквивалент VB будет.

Ответ 19

Как отметил Крис Данауэй, VB.NET имеет модули, которые позволяют вам определять функции и данные.

VB.NET имеет синтаксис VB6 для связи с методами в DLL. Например:

Declare SetSuspendState Lib "powrprof" As Function (byval hibernate as Int32, byval forceCritical as Int32, byval disableWakeEvent) as Int32

(Хотя это фактическое объявление, возможно, должно быть Marshalled)


Ответ 20

Глобальные переменные не существуют в С#, я думаю,

Ответ 21

True в VB.Net при преобразовании в целое число преобразуется в -1, а в С# - в 1.

Кроме того, ключевое слово NOT в VB.Net действительно является побитовым NOT (как в С# '~'), а не логическим NOT (С# '!').

В то время как для операторов AND и OR у VB.Net уже есть логические операторы AndAlso And OrElse, которые являются истинными логическими операторами и короткое замыкание, до сих пор нет логического NOT.

Это особенно важно при работе с Win32 API, в котором НЕ делает вывод о том, что если результат True, NOT будет отрицать его, это неверно, поскольку в C true == 1 и, следовательно, побитовое NOT на 1 также является истинным значением (и на самом деле это, вероятно, является причиной того, что в VB true == -1, поскольку это единственное значение, по которому поразрядное NOT приведет к 0)