locked
Error: Expression does not produce a value. RRS feed

  • Question

  • 'I am having trouble with the line "senda = suba(sendaobj, EventArgs.Empty)".  The Error states:
    "Expression does not produce a value."

    Private

     

    Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
         Dim a1, a2, a3 As Integer
         Dim senda As System.Object()
         a1 = 5
         a2 = 21
         a3 = 57
         Dim sendaobj() As System.Object = {CType(a1, System.Object), CType(a2, System.Object), CType(a3, System.Object)}
         senda = suba(sendaobj, EventArgs.Empty)
    End Sub
    Private Sub suba(ByVal sender As System.Object, ByVal e As System.EventArgs)
          Dim receiveobj As System.Object
          Dim a1, a2, a3 As Int32
          If sender IsNot Nothing AndAlso TypeOf sender Is System.Object Then
               receiveobj = CType(sender, System.Object)
               a1 = receiveobj.a1
               a2 = receiveobj.a2
               a3 = receiveobj.a3
          End If
    End Sub

    Wednesday, October 28, 2009 4:30 PM

Answers

  • This is my correct working answer.  The second subroutine has late binding in it.  How do I use the prefered early binding?  If you know a better way please comment!

    Private

     

     

    Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
         Dim a1, a2, a3 As Int32
         Dim ax As New Values
         With ax
             .a1 = 5
             .a2 = 21
             .a3 = 57
         End With
         suba(ax, EventArgs.Empty)
    End Sub
    Private Sub suba(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Dim receiveobj As System.Object
    Dim a1, a2, a3 As Int32
    If sender IsNot Nothing AndAlso TypeOf sender Is Values Then
         receiveobj = CType(sender, System.Object)
         a1 =
    CType(receiveobj.a1, Int32)
         a2 =
    CType(receiveobj.a2, Int32)
         a3 =
    CType(receiveobj.a3, Int32)
         MsgBox(
    "a1=" & a1)
    End If
    End Sub
         Public Class Values
         Public a1 As Int32
         Public a2 As Int32
         Public a3 As Int32
    End Class
    • Marked as answer by Jeff Shan Monday, November 2, 2009 7:36 AM
    Wednesday, October 28, 2009 6:32 PM
  • You can avoid late binding by changing the type of the first argument in the declaration of the sub from Object to the actual type of the variable you will be using.  Then you do not need to do the type checking and type conversion.

    But your code as presented here doesn't make any sense.  Why are you using a parameter of type Object in suba when you know that you will be passing a parameter of type Values?  Why are you passing an empty EventArgs when you aren't using it? Why are you converting the sender (which is already an Object) to an Object, then attempting to process it as if it were a Values?

    Perhaps if you explained what this code is attempting to achieve someone could re-arrange it to avoid late binding. 

    Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
         Dim a1, a2, a3 As Int32
         Dim ax As New Values
         With ax
             .a1 = 5
             .a2 = 21
             .a3 = 57
         End With
         suba(ax)
    End Sub
    
    Private Sub suba(ByVal V As Values)
         MsgBox("a1=" & V.a1.ToString)
    End Sub
    
    Public Class Values
         Public a1 As Int32
         Public a2 As Int32
         Public a3 As Int32
    End Class
    • Marked as answer by Jeff Shan Monday, November 2, 2009 7:36 AM
    Wednesday, October 28, 2009 10:03 PM
  • Hi Philosophaie.  You problem is that you are using a variable of type Object in suba when you shoudl be setting its type as Values.  So the line 

    Dim receiveobj As System.Object

    should look like this:

     Dim receiveobj As Values = CType(sender,Values)

    ... which is exactly what I showed you in your previous thread (where, coincidently, I also proposed you use the class "Values").  You need to convert the object argument sender to the specific type Values to be able to access the property "a1" and the other properties.  As I said before, I strongly recommend that you find a beginner book on VB and learn the basics because relying on the varied and often contradictory answerers in this forum is no substitute for a real base knowledge of object oriented design.  Please consider it.


    @CrazyPenny:  Everything I've read (no sources on hand - but easy to Google) suggests that, at best, structures are for special cases where efficiency is critical and that when given the choice, classes are just a better option in VB (I think C# offers some better reasons to use struct).  I truly do not want to turn this thread into a discussion about structure vs class, so I'll leave it be regardless if you choose to clarify.  It would, however, make a good new discussion thread if you or I were so inclined.  Of course, it's been hashed out so many times before on other forums and in articles that it's probably not worth the effort to flog this dead horse :)
    • Marked as answer by Jeff Shan Monday, November 2, 2009 7:37 AM
    Thursday, October 29, 2009 12:29 AM

All replies

  • This is my correct working answer.  The second subroutine has late binding in it.  How do I use the prefered early binding?  If you know a better way please comment!

    Private

     

     

    Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
         Dim a1, a2, a3 As Int32
         Dim ax As New Values
         With ax
             .a1 = 5
             .a2 = 21
             .a3 = 57
         End With
         suba(ax, EventArgs.Empty)
    End Sub
    Private Sub suba(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Dim receiveobj As System.Object
    Dim a1, a2, a3 As Int32
    If sender IsNot Nothing AndAlso TypeOf sender Is Values Then
         receiveobj = CType(sender, System.Object)
         a1 =
    CType(receiveobj.a1, Int32)
         a2 =
    CType(receiveobj.a2, Int32)
         a3 =
    CType(receiveobj.a3, Int32)
         MsgBox(
    "a1=" & a1)
    End If
    End Sub
         Public Class Values
         Public a1 As Int32
         Public a2 As Int32
         Public a3 As Int32
    End Class
    • Marked as answer by Jeff Shan Monday, November 2, 2009 7:36 AM
    Wednesday, October 28, 2009 6:32 PM
  • You have tried to use an expression that does not produce a value in a value-producing context, such as calling a Sub in a context where a Function is expected.

    Error ID: BC30491

    To correct this error

    • Change the expression to one that produces a value.


    Don't judge me, just Upgrade me. Thanks!
    Wednesday, October 28, 2009 9:46 PM
  • You can avoid late binding by changing the type of the first argument in the declaration of the sub from Object to the actual type of the variable you will be using.  Then you do not need to do the type checking and type conversion.

    But your code as presented here doesn't make any sense.  Why are you using a parameter of type Object in suba when you know that you will be passing a parameter of type Values?  Why are you passing an empty EventArgs when you aren't using it? Why are you converting the sender (which is already an Object) to an Object, then attempting to process it as if it were a Values?

    Perhaps if you explained what this code is attempting to achieve someone could re-arrange it to avoid late binding. 

    Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
         Dim a1, a2, a3 As Int32
         Dim ax As New Values
         With ax
             .a1 = 5
             .a2 = 21
             .a3 = 57
         End With
         suba(ax)
    End Sub
    
    Private Sub suba(ByVal V As Values)
         MsgBox("a1=" & V.a1.ToString)
    End Sub
    
    Public Class Values
         Public a1 As Int32
         Public a2 As Int32
         Public a3 As Int32
    End Class
    • Marked as answer by Jeff Shan Monday, November 2, 2009 7:36 AM
    Wednesday, October 28, 2009 10:03 PM

  • Using a class to define a type the way you do it is wrong, use a structure
    This what your code should be:



    Public Class Form1
    
        Private Structure value
            Dim a1, a2, a3 As Int32
        End Structure
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim AX As value
            AX.a1 = 5
            AX.a2 = 21
            AX.a3 = 57
            suba(AX)
        End Sub
    
        Private Sub suba(ByVal AX_Value As value)
            Dim a1, a2, a3 As Int32
            a1 = AX_Value.a1
            a2 = AX_Value.a2
            a3 = AX_Value.a3
            MsgBox("a1=" & a1)
        End Sub
    
    End Class
    Wednesday, October 28, 2009 11:34 PM
  • It's certainly not 'wrong' although you may have some reasons for preferrng a structure over a class.  There is no downside to using a class instead of a structure in this case, and I think it's useful to keep the adjusted version as similar to the original as possible, especially as changing from a class to a structure means changing from a reference type to a value type, and this example is all about type conversions between the class and an Object (even if we don't know what OP is actually trying to do). 
    Thursday, October 29, 2009 12:25 AM
  • Hi Philosophaie.  You problem is that you are using a variable of type Object in suba when you shoudl be setting its type as Values.  So the line 

    Dim receiveobj As System.Object

    should look like this:

     Dim receiveobj As Values = CType(sender,Values)

    ... which is exactly what I showed you in your previous thread (where, coincidently, I also proposed you use the class "Values").  You need to convert the object argument sender to the specific type Values to be able to access the property "a1" and the other properties.  As I said before, I strongly recommend that you find a beginner book on VB and learn the basics because relying on the varied and often contradictory answerers in this forum is no substitute for a real base knowledge of object oriented design.  Please consider it.


    @CrazyPenny:  Everything I've read (no sources on hand - but easy to Google) suggests that, at best, structures are for special cases where efficiency is critical and that when given the choice, classes are just a better option in VB (I think C# offers some better reasons to use struct).  I truly do not want to turn this thread into a discussion about structure vs class, so I'll leave it be regardless if you choose to clarify.  It would, however, make a good new discussion thread if you or I were so inclined.  Of course, it's been hashed out so many times before on other forums and in articles that it's probably not worth the effort to flog this dead horse :)
    • Marked as answer by Jeff Shan Monday, November 2, 2009 7:37 AM
    Thursday, October 29, 2009 12:29 AM


  • My understanding is that the OP just wanted to create a type. Of course, for what we know about his application, I may be wrong.

    My way to see that, is: using a class to hold 3 integers, and create only one instance of this class is just a way to make an application difficult to read. But, your argument that it work as good is right.

    I think that the OP should let us know what he is trying to do.



    Thursday, October 29, 2009 12:43 AM

  • @CrazyPenny:  Everything I've read (no sources on hand - but easy to Google) suggests that, at best, structures are for special cases where efficiency is critical and that when given the choice, classes are just a better option in VB (I think C# offers some better reasons to use struct).  I truly do not want to turn this thread into a discussion about structure vs class, so I'll leave it be regardless if you choose to clarify.  It would, however, make a good new discussion thread if you or I were so inclined.  Of course, it's been hashed out so many times before on other forums and in articles that it's probably not worth the effort to flog this dead horse :)

    here what value is can be easily locate, but imagine that you are reading an application of a few thousand line, using a class to create a simple type will mean that you will have to search thru all these line to find what Value is,

    This make the application very difficult to read
    Thursday, October 29, 2009 12:53 AM
  • MS has a commentary, which is probably the most sutiable reference for this place:

    http://msdn.microsoft.com/en-us/library/aa289521(VS.71).aspx

    which concludes :
    If your container type does not fit clearly into either of [the above] categories, define a Class. Classes are more flexible than structures, and the storage and performance differences are often negligible. Structures are intended primarily for types that behave like built-in types, not necessarily for general-purpose use.
    Thursday, October 29, 2009 12:54 AM


  • Still think that readability is more important then any "may be" or "Probably be" more suitable

    Thursday, October 29, 2009 1:06 AM

  • Still think that readability is more important then any "may be" or "Probably be" more suitable


    Then we may both be right -- because if the performance difference is negligable then maybe the deciding factor(s) could be something like readability.

    Devil's advocate though - you don't have to search through lines to see what the type is when intellisense tells you by hovering over it, and you can right click and use Goto Definition to jump to its declaration.  But we're discussing matters of style, and such things cannot be definitively right or wrong.

    Thanks for the link Acamar.
    Thursday, October 29, 2009 12:31 PM


  • Agree with you dig-Boy, this is a case of style, I also like the behaviour of the intellisence with a structure that will act the same way then, as exemple, when you set a color proprety

    I would however not suggest to use a structure to hold a functionality or a property.
    Thursday, October 29, 2009 1:05 PM
  • see here the MSDN Info: http://msdn.microsoft.com/en-us/library/5c9654de.aspx
    Friday, May 3, 2013 6:30 AM