tags:

views:

456

answers:

20

This is code-related as in what the compiler will allow you to do in one language, but not allow you to do in another language (e.g. optional parameters in VB don't exist in C#).

Please provide a code example with your answer, if possible. Thank you!

+3  A: 

The semi-colon that ends up every line in C# is prohibited in VB, and that always makes me smile when I try going back to VB.Net...

m_oLogin
That's not strictly true you can do this:';:-)
RichardOD
really? i've always wondered! :)
m_oLogin
+5  A: 

VB and C# have different interpretations of what "protected" means.

Here's an explanation copied below:

The default constructor for WebControl is protected.

VB and C# have different interpretations of what "protected" means.

In VB, you can access a protected member of a class from any method in any type that derives from the class.

That is, VB allows this code to compile:

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

Because a "Derived1" is a base, it can access protected members of "other", which is also a base.

C# takes a different point of view. It doesn't allow the "sideways" access that VB does. It says that access to protected members can be made via "this" or any object of the same type as the class that contains the method.

Because "Foo" here is defined in "Derived1", C# will only allows "Foo" to access "Base" members from a "Derived1" instance. It's possible for "other" to be something that is not a "Derived1" (it could, for example, be a "Derived2"), and so it does not allow access to "m_x".

Tom Ritter
If I'm reading this correctly, C#'s protected internal gets around this.
R. Bemrose
@R. Bemrose - my understanding is that the two are orthogonal; the protected issue would still apply across multiple assemblies.
Marc Gravell
+4  A: 

Off the top of my head (pre 4.0):

VB language "features" not supported in C#:

  • Optional Parameters
  • Late Binding
  • Case insensativity

I'm sure there's more. Your question might get better answers if you ask for specific examples of where each language excels. VB is a currently better than C# when interacting with COM. This is because COM is much less of a headache when optional parameters are available, and when you don't have to bind to the (often unknown type) at compile time.

C# on the other hand, is preferable by many when writing complex logic because of its type safety (in that you can't bypass static typing) and its conciseness.

In the end, the languages are mostly equivalent, since they only differ on the fringes. Functionally, they are equally capable.

EDIT

To be clear, I'm not implying that VB doesn't allow static typing... simply that C# doesn't [yet] allow you to bypass static typing. This makes C# a more attractive candidate for certain types of architectures. In the 4.0 C# language spec, you can bypass static typing, but you do it by defining a block of dynamic code, not by declaring the entire file "not strict," which makes it more deliberate and targeted.

Michael Meadows
VB.NET has Lambdas
Dennis Palmer
Didn't know. I'll take it out.
Michael Meadows
C# 4.0 has optional parameters. They didn't want them, but not having them makes legacy COM a hassle.
Brian
@Brian, I knew that was coming in 4.0. In fact, one of the focuses of the language changes in C# for 4.0 seems to be to bridge the COM gap, which makes the languages even more equivalent. I'm not sure why they don't try to specialize then languages more instead of making them more similar... as a developer, I don't need two languages that are so similar that my only reason to choose one over the other is subjective (my affinity for semicolons or the words "Then" and "End").
Michael Meadows
I'd remove the comment about static typing. `Option Strict` allows typing that is just as strict as C#'s. VB, for all intents and purposes, is type safe.
Konrad Rudolph
@Konrad Rudolph, it's true, however, that you can bypass static typing in VB, and you cannot in C#. I did intentionally choose the word "bypass". Even that, though, is going away in 4.0 with the "dynamic" keyword.
Michael Meadows
The thought of case insensitive code makes me shudder. But I guess it is all a matter of what you are used to. And I guess it's kind of funny, because the exact opposite is true for sql, the thought of writing a case sensitive sql query makes me shudder.
Kevin
I changed it from "VB language benefits" to "VB language 'features'" when I added case insensitivity. :) A lot of the language differences in VB seem to be throwbacks to support migrated VB6 code that they're just stuck with now. The funny thing is that it has almost come full circle, with C# adopting a lot of what we used to scoff at as legacy features in VB.
Michael Meadows
VB.NET with `Option Strict On` is *still* not as type-safe as C#. One example off the top of my head: non-string types are silently converted to strings if they are embedded in a string concatenation expression.
Christian Hayter
@Christian: as they are in C#. No difference. In fact, VB allows the use of an extra concatenation operator which doesn’t exist in C#, making string concatenations even *more* unambiguous (visually) than in C#.
Konrad Rudolph
+3  A: 

The new autoproperties in C# have not been done for VB.NET yet.

TheTXI
+2  A: 

The volatile keyword is only available in C# http://www.devcity.net/Articles/160/5/article.aspx

Kane
+1  A: 

In C# you have to assign your variable before you can use it. I think you can turn this off, but it's the default behavior.

So something like this:

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

Isn't allowed, but the VB equivalent would be.

Joseph
It's even stranger when you consider that Java, the language C# copied, allows that (ints have a default value of 0). At a guess, MS didn't like that Java allowed you to do that so C# doesn't allow it. But, since VB6 did it, they left it in Vb.NET.
R. Bemrose
+10  A: 

I'm surprised that C#'s unsafe code has not been mentioned yet. This is not allowed in VB.NET.

Tomas Lycken
+12  A: 

VB.NET has support for CIL Exception Filters, C# doesn't:

Try 
  ...
Catch ex As SomeException When ex.SomeProperty = 1
  ...
End Try
bzlm
Hey, that's pretty cool. I think I'm going to convert all my source from C# to VB now! Seriously, though, that's cool, hope the C# team picks up on this.
Michael Meadows
+1 and here's where the NET CLR team blog explains why exception filters are useful http://blogs.msdn.com/clrteam/archive/2009/02/05/catch-rethrow-and-filters-why-you-should-care.aspx
MarkJ
+5  A: 

In VB you can implement an interface with a method of any name - i.e. a method "Class.A" can implement interface method "Interface.B".

In C#, you would have to introduce an extra level of indirection to achieve this - an explicit interface implementation that calls "Class.A".

This is mainly noticeable when you want "Class.A" to be protected and/or virtual (explicit interface implementations are neither); if it was just "private" you'd probably just leave it as the explicit interface implementation.

C#:

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

In the IL, VB does this mapping directly (which is fine; it is not necessary for an implementing method to share a name).

Marc Gravell
+2  A: 

One of my favorites (and bummers)

In VB.Net you can struture a switch/case statement as such:

Select Case True

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

End Select

which allows you to evaluate some complex evaluations through a switch instead of a variety of if/else blocks. You cannot do this in C#.

Dillie-O
This syntax has always thrown me, as it's nothing more than an If statement masquerading as a Case.
R. Bemrose
My initial reaction is "Holy crap is that ugly code. I would slap someone for writing that." But I'm trying to be fair and consider if it would ever be useful
Kevin
You can run into situations where where you evaluate clause A, then go down and evaluate clause B and C if A is true or evaluate C and D if A is false, and so on. Being able to line them out in single line evaluations to a single true/false helps readability.
Dillie-O
I'm doing some ugly nested case-if statements in C# right now and I find myself wishing I could do this...
muusbolla
VB's ability to do `Select Case` on pretty much anything is nice too
Pondidum
A: 

Global variables don't exist in c# i think

Noctris
Good call, and global methods... although I say good riddance to both.
Michael Meadows
Nor do they exist in VB.Net either! VB.Net allows you to have a Module which kind of looks like global variables, but in reality it is just a class under the hood with all static members.
Chris Dunaway
@Chris Dunaway, regardless of how it's wired, it is still treated as global by VB. Both the VB and C# compilers are chock full of "tricks" that make the languages appear to do more than the CLI supports. In the end, though, if I declare a variable "public i as Int32" in a public module, I can access it "Debug.WriteLine(i)" from anywhere in VB.
Michael Meadows
+8  A: 

The VB 9.0 compiler automatically translates literal XML into "functional construction" syntax. The C# compiler does not support this nice literal XML syntax.

dss539
XML literals are a very appealing aspect of VB!
Funka
+5  A: 

VB allows nonvirtual calls to virtual instance methods (call in IL), whereas C# only allows virtual calls (callvirt in IL). Consider the following code:

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()

The output is:

Derived
Base

That's not possible in C# (without resorting to Reflection.Emit).

Konrad Rudolph
+5  A: 

There were some useful articles in Visual Studio magazine back in Jan 2008.

MarkJ
+3  A: 

Indexed properties are allowed in VB.NET, but not in C#

    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
slolife
@R.Bemrose: That's not the same thing! It is similar, but in C# you can only have one indexer. IIRC, in VB.Net you can have any number of properties that have indexes.
Chris Dunaway
+3  A: 

VB has optional parameters on functions.

C# will only get these with C# 4.0

rein
+6  A: 

Handles and WithEvents keywords for automatic wiring of EventHandlers.

Private Sub btnOKClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOK.Click
End Sub
Lurker Indeed
+1  A: 

As Chris Dunaway mentioned, VB.NET has Modules which allow you to define functions and data.

VB.NET has the VB6 syntax for linking to methods in DLLs. For example:

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

(Although that actual declaration might have to be Marshalled)


Modules - aaargh! Now if they added an attribute that removed module members from the global namespace, they would be genuinely useful. Please someone tell me it exists and I just haven't found it yet. :-(
Christian Hayter
+3  A: 

In C# you can declare a property in an interface as having a 'get', and then implement it in a class with a get and set.

public interface IFoo {
  string Bar {get;}
}

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

In VB, the equivalent to declating a property with a get would be to declare it ReadOnly. You can't then make the implementation writable.

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

I find this to be a severe limitation of VB. Quite often I want to define an Interface that allows other code only to be able to read a property, but I need a public setter in the implemented class, for use by the persistor.

Richard Pawson
+3  A: 

One of the overlooked or simply misunderstood features of the VB language is calling a function which has a ByRef parameter. Most languages support only a single method of passing parameters by reference: that is the scenarios directly supported by the CLR.

The CLR has a lot of restrictions on the type of values it supports for ByRef parameters and these restrictions get in the way of VB’s goal to be a flexible language. Hence the compiler goes to great lengths to be flexible and support multiple avenues of ByRef passing, much beyond what the CLR natively allows.

C# 4 now supports two versions of reference passing. In addition to the one available since 1.0 the ref modifier is now optional when making an interop call to a COM object.

MarkJ