Why does this work?

B

Bob Altman

This code (Visual Studio 2005) should generate a compilation warning to the
effect that I'm accessing a shared member through an instance variable (the
"color" variable):

Private Sub X(ByVal color As Color)
Me.BackColor = color.AliceBlue
End Sub

On *some* computers this produces the expected warning. On others it does
not. Any clue what setting is causing some computers to fail to complain?

TIA - Bob
 
F

Family Tree Mike

Vb.net is not case sensitive, so in general, having a variable called color
could be bad.

Change the parameter to colorparam and then the line to Me.BackColor =
colorparam.AliceBlue, and I bet you get the warning everywhere.
 
J

James Hahn

'Instance variable accesses shared member' warning is configurable, so
it is set to Warning on some of those machines, and None on the others.
 
S

Scott M.

Whether you get an error or warning or not is dependant on that particular
compiler settings (in the project's properties).

But, actually, you code is NOT accessing a shared member through an instance
variable.

An instance variable is one where you make an instance (implicitly or
explicitly) and assign a variable to it - - your code is not doing that, it
is associating a variable (color) to represent a static type. But, when you
write color.AliceBlue, the compiler doesn't see your capitalization of
color, it sees that you are attempting to access the members of a type
called "color" and since there is a type in the .NET framework called
"color", the compiler knows you are using the shared members of the color
type and not your color parameter name.

In C#, this code would be no problem since it is a case-sensitive language,
but in VB it can make your code tough to troubleshoot. As the other reply
said, when naming variables do more than change the case.

-Scott
 
J

James Hahn

The code IS accessing a shared member through an instance variable. The
compiler will always make the access through the class or structure name
instead of evaluating the expression. The warning exists because the syntax
is legal, but the compiler action may be unexpected.
 
B

Bob Altman

That much is obvious. The question is: Where is that configuration setting
hidden?
 
S

Scott M.

No James. No instance variable is being used here.

Here's an example that would be accessing a shared member through an
instance variable (pseudo-code)

Public Class Foo
Public Shared Property Value As String
Get
End Get
Set()
End Set
End Property
End Class

'Some other class...
Sub DoSomething()
dim f As New Foo ' <-- This is your instance variable
f.Value = "Something" '<--- This is an attempt to access a shared
member through an instance variable
End Sub

-----------

As I said, in the original example, when the compiler sees
"color.AliceBlue", it doesn't assume your are talking about the "color"
parameter, it knows to use the Color class and access its shared AliceBlue
property, which is entirely correct. No instance of the Color class has
been made (either implicitly or explicitly) and so no error occurs.

-Scott
 
B

Bob Altman

Steve Gerrard said:
In VS 2005, I go to My Project, Compile Tab, and find a list of several
Conditions, each with a choice of Notification. One of them is "Instance
variable accesses shared member," with the notification set to "Warning."
This is a project level setting.

Hmmm... Sounded promising, but that's not it. This behavior is tied to the
PC, not to the project. I checked the project settings and "Instance
variable accesses shared member" is set to Warning as expected.

Just for grins I changed the code to look like this:

Private Sub X(ByVal color As Color)
' No warning...
Me.BackColor = color.AliceBlue
End Sub

Private Sub Y(ByVal a As Color)
' Warning: "Access of shared member...through an instance..."
Me.BackColor = a.AliceBlue
End Sub

On my PC the "color.AliceBlue" expression compiles without warning. But on
my co-worker's computer it gets the "Access of shared member...through an
instance..." warning.
 
J

James Hahn

No. The difference between what the code is doing and what the compiler is
doing is the reason for the warning.
 
J

James Hahn

The variable 'color' is an instance of the class 'Color', created in the Sub
declaration. The Color class includes shared readonly properties (the named
colors), so the reference within the sub to 'color.AliceBlue' is a reference
to the shared member (AliceBlue) using the instance 'color'. That's why the
warning appears.

In OP's case the issue is confused by the fact that a class name has been
used as the instance name. You can see what's actually happening by checking
the definition of 'color' (the instance, that is, as in 'color.AliceBlue').
The compiler doesn't automatically use the class instead of the instance
simply because there's a naming conflict. The compiler has detected that the
instance variable is being used to reference the shared member and has
provided a warning so that the programmer is aware that the compiler has
taken the source code to mean something other than what the programmer
wrote. But the code as written is using the instance variable, and that's
why the warning has appeared.
 
A

Armin Zingler

Scott M. said:
No James. No instance variable is being used here.

James is right. See below.
Here's an example that would be accessing a shared member through an
instance variable (pseudo-code) [...]

That's right.
As I said, in the original example, when the compiler sees
"color.AliceBlue", it doesn't assume your are talking about the
"color" parameter, it knows to use the Color class and access its
shared AliceBlue property, which is entirely correct. No instance
of the Color class has been made (either implicitly or explicitly)
and so no error occurs.

The compiler resolves names inside out. In this example

Private Sub X(ByVal color As Color)
Me.BackColor = color.AliceBlue
End Sub

the 2nd line accesses 'color'. When doing name resolution, the compiler
finds the _argument_ named color. This is definitely an instance variable.
Therefore, color.AliceBlue means accessing a shared member through an
instance variable. Therefore the warning.

The compiler does _not_ overlook the argument color, therefore it does _not_
find the (imported) (System.Drawing.)Color type. You would have to use
System.Drawing.Color, or Drawing.Color as the System namespace is imported
by default, to refer to the _type_ Color.

Though, this does not explain why the OP has different behavior on different
machines as long as the project's warning settings are the same. Maybe the
"warnings" check box is just not checked in the error/warnings window on the
other machine.


Armin
 
B

Bob Altman

Though, this does not explain why the OP has different behavior on
different
machines as long as the project's warning settings are the same. Maybe the
"warnings" check box is just not checked in the error/warnings window on
the
other machine.

Nice try, but that's not it. Not only is there no warning message in the
error/warnings window (and, yes, I verified that warnings are enabled) but
there also is no wavy underline in the code window.

And, as I noted in another branch of this discussion, I verified that the
problem machine *does* generate the expected warning if the local variable
name is different than the class name, like this:

Private Sub X(ByVal color As Color)
' No warning...
Me.BackColor = color.AliceBlue
End Sub

Private Sub Y(ByVal a As Color)
' Warning: "Access of shared member...through an instance..."
Me.BackColor = a.AliceBlue
End Sub

On my PC the "color.AliceBlue" expression compiles without warning. But on
my co-worker's computer it gets the "Access of shared member...through an
instance..." warning.
 
F

Family Tree Mike

Can someone explain to me why I only get the warning in the code below if
the argument is renamed to something other than "color"? In other words,
the code as is, gives no warning. The modified code using "colora" as the
parameter and using Me.BackColor = colora.AliceBlue, gives the warning.

I'm using Visual Studio Pro 2008, which I reallize is different than the OP.
 
A

Armin Zingler

Bob Altman said:
Private Sub X(ByVal color As Color)
' No warning...
Me.BackColor = color.AliceBlue
End Sub

Private Sub Y(ByVal a As Color)
' Warning: "Access of shared member...through an instance..."
Me.BackColor = a.AliceBlue
End Sub

On my PC the "color.AliceBlue" expression compiles without warning. But on
my co-worker's computer it gets the "Access of shared
member...through an instance..." warning.

I don't know why I haven't tested it on my machine, yet. .... Did it now:
I do not get a warning in Sub X. My next thought was, it might be SP1 on one
machine and not on the other. I tried it on another machine without SP1....
No warning in Sub X, also. Same with a another machine without SP1.



Armin
 
A

Armin Zingler

Scott M. said:
As I said, in the original example, when the compiler sees
"color.AliceBlue", it doesn't assume your are talking about the "color"
parameter, it knows to use the Color class and access its shared AliceBlue
property, which is entirely correct. No instance of the Color class has
been made (either implicitly or explicitly) and so no error occurs.

In addition...
You are saying that color.AliceBlue refers to the _type_ color, right? Then
this line must not work because 'R' is an instance member:

sub x(byval color as color)
dim b as byte = color.R
end sub

Though, it is compilable. Obviously there seems to be a contradiction in in
the compiler's behavior, IMO. - strangely not on each of Bob's machines,
whyever.


Armin
 
J

Jack Jackson

I tried this on both VS2005 and VS2008, and I don't get the warning in
either.

However, if I use DateTime instead of Color, I do get the warning in
both:

Private Sub Y(ByVal datetime As DateTime)
Dim xx As DateTime

datetime.AddDays(5) ' Instance Method, no error
datetime.FromBinary(9) ' Shared Method, error
xx = datetime.MaxValue ' Shared Property, error
 
K

kimiraikkonen

This code (Visual Studio 2005) should generate a compilation warning to the
effect that I'm accessing a shared member through an instance variable (the
"color" variable):

  Private Sub X(ByVal color As Color)
    Me.BackColor = color.AliceBlue
  End Sub

On *some* computers this produces the expected warning.  On others it does
not.  Any clue what setting is causing some computers to fail to complain?

TIA - Bob

Using VB 2005 Express with .NET 2.0 with default settings, it gives
the warning but it doesn't hurt the compilation. VS offers me to
change the line.
 
S

Scott M.

James Hahn said:
The variable 'color' is an instance of the class 'Color', created in the
Sub declaration.

No, it is not and that's the source of your confusion. The variable color
isn't an "instance" of the class it is simply a parameter variable that
shadows the Color type's name. The compiler is able to tell the difference
between the two by the context in which the word "color" is used. Not to
mention that parameters don't create instances in the first place, they are
variables that are either passed a data value or a reference to either a
data value or a memory location where an object is stored. Parameters don't
instantiate anything.
The Color class includes shared readonly properties (the named colors), so
the reference within the sub to 'color.AliceBlue' is a reference to the
shared member (AliceBlue) using the instance 'color'. That's why the
warning appears.

Your close, but not quite correct here. There is no instance of Color.
That's the whole point of shared type members, you don't call them from an
instance. As the OP states, he is NOT getting a warning about this line of
code and the reason he's not is because Color.AliceBlue is understood by the
compiler as accessing a shared member from a "type", not an instance.
In OP's case the issue is confused by the fact that a class name has been
used as the instance name. You can see what's actually happening by
checking the definition of 'color' (the instance, that is, as in
'color.AliceBlue'). The compiler doesn't automatically use the class
instead of the instance simply because there's a naming conflict. The
compiler has detected that the instance variable is being used to
reference the shared member and has provided a warning so that the
programmer is aware that the compiler has taken the source code to mean
something other than what the programmer wrote. But the code as written
is using the instance variable, and that's why the warning has appeared.

Again, you are wrong. There is NO instance being created here and the OP
inidcated that he wasn't getting a warning - - only in some cases was a
warning showing up. But, we've already answered the question about the
warning as being related to difference machine's different compiler warning
tolerance settings.

-Scott
 
S

Scott M.

I disagree with your interpretation of what's going on here. Regardless of
"inside out" processing. Passing a parameter does not cause an instance of
anything to be made as parameters either receive a copy of data or a copy of
a reference to an "already existing" object. There is no instance being
created by this code.


Armin Zingler said:
Scott M. said:
No James. No instance variable is being used here.

James is right. See below.
Here's an example that would be accessing a shared member through an
instance variable (pseudo-code) [...]

That's right.
As I said, in the original example, when the compiler sees
"color.AliceBlue", it doesn't assume your are talking about the
"color" parameter, it knows to use the Color class and access its
shared AliceBlue property, which is entirely correct. No instance
of the Color class has been made (either implicitly or explicitly)
and so no error occurs.

The compiler resolves names inside out. In this example

Private Sub X(ByVal color As Color)
Me.BackColor = color.AliceBlue
End Sub

the 2nd line accesses 'color'. When doing name resolution, the compiler
finds the _argument_ named color. This is definitely an instance variable.
Therefore, color.AliceBlue means accessing a shared member through an
instance variable. Therefore the warning.

The compiler does _not_ overlook the argument color, therefore it does
_not_
find the (imported) (System.Drawing.)Color type. You would have to use
System.Drawing.Color, or Drawing.Color as the System namespace is imported
by default, to refer to the _type_ Color.

Though, this does not explain why the OP has different behavior on
different
machines as long as the project's warning settings are the same. Maybe the
"warnings" check box is just not checked in the error/warnings window on
the
other machine.


Armin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top