7 Replies - 11856 Views - Last Post: 24 October 2012 - 06:03 AM

#1 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2271
  • View blog
  • Posts: 9,499
  • Joined: 29-May 08

Why do VB.net & C# differ in behavior here?

Post icon  Posted 21 October 2012 - 09:04 PM

As for as I can tell the following two code examples are exactly the same in functionality.

C#
namespace ConsoleApplication4
{
 class Program
 {
  static void Main(string[] args)
  {
   var x = new Example(12);
   var y = new Example(34);
   var z = Example.Examples.One;
  }
 }
 class Example
 {
  public static class Examples
  {
   public static readonly Example Zero = new Example(0);
   public static readonly Example One = new Example(1);
  }
  public readonly Double Value;
  public Example(Double Value)
  {
   this.Value = Value;
  }
  public static Example Add(Example x, Example y)
  {
   return new Example(x.Value + y.Value);
  }
 }
}



VB.net
Option Strict On
Module Module1

    Sub Main()

    Dim x=New Example(12)
    Dim y = New Example(34)
    Dim z=  Example.Examples.One
    End Sub

End Module

Public Class Example

  Public  Class Examples
    Public Shared ReadOnly Zero As Example
    Public Shared ReadOnly One As Example
    Public Shared ReadOnly Two As Example
    Public Shared ReadOnly MinusOne As Example
    Shared Sub new()
      Zero=New Example(0)
      One= New Example(1)
      Two = New Example(2)
      MinusOne = New Example(-1)
    End Sub
  End Class
  Public ReadOnly Value As Double
  Public Sub New(Value As Double)
    Me.Value=Value
  End Sub
  Public Shared Function Add(x As Example,y As Example) As Example
    Return New Example(x.Value+y.Value)
  End Function
End Class



So OK on to the issue I having.

var z = Example.Examples.One; 


if I do a . after the One, I only get the instance methods.

Now if I do the following in VB.net
  Dim z=  Example.Examples.One.


I not only get the Instance methods but I also get the Examples

Now if this because it is Shared / Static you would also expect the .Add method to be there also but it isn't. :surrender:

Ideally it should behave the same.

Just to rule out it is an issue with my code, I'll provide an example from .net framework that also has the same behavior. System.Drawing.Color
Where you can do Dim c = Color.Red.Black.Blue.Pink ? That's results in c = Color.Pink.


I've had some rather uninformative answers that it's for compatibility reasons with vb6, but trying find out what those actual reasons are (preferably code examples) is rather like trying to extract information out a Bureaucracy Agency.

:helpsmilie:

  • Do you know the reason?
  • Can show examples?
  • Know how to turn it off.
  • Or is there an advantage? to the way VB.net does it?


Is This A Good Question/Topic? 1
  • +

Replies To: Why do VB.net & C# differ in behavior here?

#2 lucky3  Icon User is offline

  • Friend lucky3 As IHelpable
  • member icon

Reputation: 231
  • View blog
  • Posts: 769
  • Joined: 19-October 11

Re: Why do VB.net & C# differ in behavior here?

Posted 21 October 2012 - 09:25 PM

Option Infer Off. Nope.

This post has been edited by lucky3: 21 October 2012 - 09:32 PM

Was This Post Helpful? 0
  • +
  • -

#3 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2271
  • View blog
  • Posts: 9,499
  • Joined: 29-May 08

Re: Why do VB.net & C# differ in behavior here?

Posted 21 October 2012 - 09:31 PM

View Postlucky3, on 22 October 2012 - 05:25 AM, said:

Option Infer Off.


Still the same behavior with explicit type the variables declarations.
Option Strict On
Option Infer off
Module Module1

    Sub Main()

    Dim x As Example =New Example(12)
    Dim y AS Example = New Example(34)
    Dim z As Example = Example.Examples.One
    End Sub

End Module


This post has been edited by AdamSpeight2008: 21 October 2012 - 09:33 PM

Was This Post Helpful? 0
  • +
  • -

#4 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4425
  • View blog
  • Posts: 12,293
  • Joined: 18-April 07

Re: Why do VB.net & C# differ in behavior here?

Posted 21 October 2012 - 09:35 PM

I see the .Add method for the VB.NET version. Because you do Dim z = Example.Examples.One you should see all methods of Example (since that is what "One" is defined as ... Public Shared ReadOnly One As Example and when I put the period I will see all methods of Example (which includes .Add()) and "Examples" because it is a member of Example.

Are you sure you have the intellisense tab selected to "All"? If you have it on "Common" you won't see Add(). Notice in the screenie below...

Attached Image

This is what I see. I don't see anything wrong here. I see Add(). Or are you talking about not seeing it in C#?

This post has been edited by Martyr2: 21 October 2012 - 09:35 PM

Was This Post Helpful? 1
  • +
  • -

#5 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2271
  • View blog
  • Posts: 9,499
  • Joined: 29-May 08

Re: Why do VB.net & C# differ in behavior here?

Posted 21 October 2012 - 09:56 PM

Not there in mine (VS2012 Express for Desktop)
VB.net
Attached Image
Excuse the color-scheme.

Example.Examples isn't a member it's a inner class and shouldn't be there in the list.
Edit: Example.Examples.One at this point is an instance of class Example.

C# Intellisense
Attached Image

Shows only instance methods.
Which I consider the correct result. As static / shared method should only accessible via the Class name.
Eg
 Dim x = Example.Examples.One
 Dim y = Example.Examples.Two
 Dim r = Example.Add(x,y)


Not
 Dim x = Example.Examples.One
 Dim y = Example.Examples.Two
 Dim r = x.Add(x,y) ' Notice this not an Extension method (Edit: Also a warning )'
 Dim r1 = x.Add(y) ' this would be an Extension method '


This post has been edited by AdamSpeight2008: 21 October 2012 - 10:14 PM

Was This Post Helpful? 0
  • +
  • -

#6 MuKuLGarg  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 7
  • Joined: 05-July 09

Re: Why do VB.net & C# differ in behavior here?

Posted 21 October 2012 - 10:40 PM

Hi,

As I think the reason for this behavior is due to compiler, or more specifically language rules.

In VB.NET, you are allowed to access the Shared(same as static in C#) through the instance of the class. So when you put a dot after Blue in System.Drawing.Color.Blue., it will shows all the members with Shared members also. the System.Color.Blue is the instance of System.Color class, and since in VB.NET you can access shared members from instance of the class, you get list of all members with shared members also, after putting dot after Blue.

In C#.NET, you can not access the static members through the instance of that class. So when you put . after System.Colo.Blue in C#, you will not get the list of static members. Also look at this, Blue is a static member of class System.Color, so if you create an instance of System.Color, you will not be able to access the Blue from that instance.

Example

In C#.Net

namespace Demo1
{
    class Class3
    {
        public static int x = 10;
    }

    class Program
    {
        Class3 c = new Class3();
        c.x = 20; //ERROR: Member 'Demo1.Class3.x' cannot be accessed with an instance reference; qualify it with a type name instead
    }
}



In VB.NET

Public Class Class1
    Public Shared x As Integer
End Class
Module Module1

    Sub Main()
        Dim c As Class1 = New Class1()
        c.x = 20 'Allowed, but will got an Error Correction Options, notification in VS 2012, to replace c.x with Class3.x
    End Sub

End Module




Now why this is so, sorry I don't know. This is in the design of the languages. Why they put in design, that i don't know.

Thanks.
Mukul
Was This Post Helpful? 1
  • +
  • -

#7 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2271
  • View blog
  • Posts: 9,499
  • Joined: 29-May 08

Re: Why do VB.net & C# differ in behavior here?

Posted 21 October 2012 - 11:48 PM

The only reason I can think of why this maybe so, is the evil Default Instances of Forms. So if this the reason why didn't they special case Forms in the compiler to allow this and not make it the default behavior for all classes.

If Paul Vick (vb language guru) has forgotten the reason why. Then I think I'm up Ship Creek without a Paddle Steamer.

This post has been edited by AdamSpeight2008: 22 October 2012 - 12:04 AM

Was This Post Helpful? 0
  • +
  • -

#8 BBeck  Icon User is offline

  • Here to help.
  • member icon


Reputation: 592
  • View blog
  • Posts: 1,320
  • Joined: 24-April 12

Re: Why do VB.net & C# differ in behavior here?

Posted 24 October 2012 - 06:03 AM

I've been watching this discussion for a couple of days (Read it on SO). I think you guys know more about this than I do. For one thing, static classes and methods is something that I'm "just" studying now. (I've been programming for a very long time, but I never formally learned C# and now I'm going back and filling in a lot of gaps in what I know on C#.)

Anyway, I believe the purpose of a static method, or in this case field, is to have it shared across all objects of the class. So, it makes sense to me that it should not be allowed to be set for an instance of the class. And it makes sense to me that the compiler would force you to assign a value at the class level.

Otherwise, you could write a bug in the program along the lines of this:

namespace Demo1
{
    class Class3
    {
        public static int x = 10;
    }

    class Program
    {
        Class3 c = new Class3();
        Class3 d = new Class3();
        c.x = 20; //Allowed in my imaginary scenario.
        d.x = 46;

        if (c.x == 20)
        {
          Console.WriteLine("I get what I expect.");
        }
        else
        {
          Console.WriteLine("But turns out this is what you ACTUALLY get.");
          Console.WriteLine("c.x=46 because .x is shared across all objects of this class.");
        }
    }
}



Anyway, that's just a guess. But my guess is that they forbid it in order to enforce the reason for the static field being there in the first place, which I believe is: that it is supposed to be shared across all instances.

If you are forced to use the class name to assign the value, then it's clear that it's shared across all instances. Whereas, if you're allowed to assign it to an instance, you would think it's been assigned to that instance, but since it's static/shared it's been assigned to ALL instances current and future.

Sounds like VB is just a little lax in enforcing it.

This post has been edited by BBeck: 24 October 2012 - 06:05 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1