views:

172

answers:

3

(I tried with this question but this code isolates the problem better.)

I have this code:

Public Shared Sub PopulateTextFields(ByRef stuffList As List(Of Stuff))
    Dim aStuff As New Stuff
    For Each aStuff In stuffList
        DoStuff(aStuff)
    Next
End Sub

Private Sub DoStuff(ByRef theStuff as Stuff)
    ....
End Sub

I get the following error highlighting DoStuff(aStuff):

Cannot refer to an instance member of a class from within a shared method or shared member initializer without an explicit instance of the class.

Didn't I get an explicit instance of Stuff when I wrote the Dim statement?

Don't understand what's wrong. Thanks in advance!

+4  A: 

Yes you did, but you aren't referencing aStuff you are trying to call it on the static implementation of the class, furthermore you are resetting aStuff to a separate instance through each loop iteration.. change your code to:

Public Shared Sub PopulateTextFields(ByRef stuffList As List(Of Stuff))
    Dim aStuff As New Stuff
    For Each aStuff In stuffList
        aStuff.DoStuff(aStuff)
    Next
End Sub

Private Sub DoStuff(ByRef theStuff as Stuff)
    ....
End Sub

And it should work, but maybe not as expected, I don't really know your intent of having a private member that handles changing a separate reference of it's own type.

It may be appropriate to change the signature of DoStuff to:

Private Sub DoStuff()
    ....
    'Use the Me reference here to change myself
    ....
End Sub

and then call it as:

aStuff.DoStuff() 'Will modify this instance
Quintin Robinson
Thanks for responding Quintin. Sorry I wasn't clear about what methods were where: DoStuff in my app was in the same scope as PopulateTextFields, and not a member method of Stuff. In any case, you taught me something.
John at CashCommons
+1  A: 

I think the problem lies with the Subroutine DoStuff. If both your subs lie in the same class, you are trying to refer to DoStuff from within PopulateTextFields, which is a shared sub.

In order to achieve this, you need to declare DoStuff as Shared as well.

Anax
That was the issue. Thank you!
John at CashCommons
+2  A: 

You didn't share which type these methods belong to. From your confusion, I'm guessing it's part of the "Stuff" class. But it doesn't really matter. It sounds like you're forgetting one of two things:

  • Creating an instance of the type in the shared method doesn't somehow attach the shared method to that instance. You could create 10 or 1000 instances in the method, after all.

  • Passing an instance as a parameter doesn't associate the function with an instance. A parameter is not a call site.

Either way, it comes down to providing an instanced call site. Your DoStuff function is not shared, and so the compiler thinks it needs access to state provided by a specific instance of your type. That instance is the method's call site. You either need an instance of the type to call it from: SomeInstance.DoStuff(aStuff) , or if the method doesn't really need access to any type state you need to mark it shared and call it like this: Stuff.DoStuff(aStuff)

Joel Coehoorn
Thanks for answering Joel! I learned some things from your answer.
John at CashCommons