1

I'm a newb to VB.NET and I'm having trouble with understanding how the Return actually works in a Function. The terminology I use will probably be incorrect but hopefully you'll understand what I'm driving toward.

I have a public module with a public function which opens an oledb connection to a csv file and gets the data. The function 'Return' csvDataSet. From my main form I can dim a new dataset (ds) and do the following:

Dim ds As New DataSet
DataGridView1.DataSource = FillDataSet(ds).Tables(0).DefaultView

DataGridView1 populates and all is well.

However, I've read that if I use a Class instead of a Module and use a Public Shared Function to return csvDataSet, it should be Static and I wouldn't need a new instance (in this case ds). I can't seem to make that work, so I know I'm missing something stupid in my understanding. If csvDataSet is Returned from a Public Shared Function inside a Public Class, should I always be able to set something to that csvDataSet i.e.

DataGridView1.DataSource = csvDataSet.Tables(0).DefaultView 'or something similar? 

I know it's not a big deal to do it the way I'm doing it and Dim ds as New DataSet and get it that way. I just want to understand why I can't just use csvDataSet if it already contains all the pertinent data. Hopefully that was a tad clearer than mud!

Adding Code as requested. Module:

Imports System.Data.OleDb
Imports System.IO
Module modGetData
    'Public strLastFirst As String

    Public Function FillDataSet(ByVal csvDataSet As DataSet) As DataSet
        Dim fi As New FileInfo("c:\prospects.csv")
        Dim connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Text;Data Source=" & fi.DirectoryName
        Dim conn As New OleDbConnection(connectionString)
        Dim cmdSelect As New OleDbCommand("SELECT * FROM " & fi.Name, conn)
        Dim adapter1 As New OleDbDataAdapter

        conn.Open()
        adapter1.SelectCommand = cmdSelect
        adapter1.Fill(csvDataSet, "DATA")
        Return csvDataSet
        conn.Close()
    End Function
End Module
Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim ds As New DataSet
        DataGridView1.DataSource = FillDataSet(ds).Tables(0).DefaultView
0

2 Answers 2

0

There is some terminology we need to be clear up:

The [FillDataSet()] function 'Return' csvDataSet.

This is minor, but Return implies something more like this:

Dim ds As DataSet = FillDataSet()
DataGridView1.DataSource = ds.Tables(0).DefaultView

or even:

DataGridView1.DataSource = FillDataSet().Tables(0).DefaultView

Notice we declare DataSet, but we did not use New. We let the variable be populated when the function returned. And because of that, we did not need to pass it to the function.

if I use ... a Public Shared Function to return csvDataSet, it [would] be Static

Static is word used often in other languages, but it means something completely different in VB.Net. When those other languages say static, you should hear it at Shared. VB.Net's Static is a different concept that does not have an equivalent in most of other languages. Using it here makes things more confusing.

I wouldn't need a new instance (in this case ds)

You still need an instance, but you would not need to create that instance locally. You can let the method create it's own instance. You can do this with a Module, too. You don't gain anything special by having a Class with a Shared method.


The important thing to understand here is the difference between a variable, an object, and a reference.

In the first code sample in the question, ds is a variable. It's a name you can use in code with a specific scope. However, this does not imply any actual memory!

Using the New keyword as part of the declaration also creates an object. The object is the actual value in memory, but this is completely separate from the ds variable.

Finally, because the ds variable is declared in the same line with the New keyword, the variable is also initialized to refer to the memory that was allocated for the DataSet object. But you can have a variable with no reference (it's Nothing). And you can have an object with many references (or none... and then the object becomes eligible for disposal). You can change with object a variable refers to.

Knowing which you mean: object, reference, or variable, as well as how they are passed and returned between functions, is extremely important to writing good and effective code.


For this question, you can create an object with New in a method, and return the result so a reference is assigned to a variable where the method was called. You would want to change the FillDataSet() method like this:

Public Function FillDataSet() As DataSet
    Dim ds As New DataSet
    ' Rest of the method is here
    Return ds
End Function

Then you would be able to call the method as I demonstrated earlier.

The reason to do this, is the less a function needs to depend on outside variables (what we call "shared state"), the easier they are to write, debug, change, and maintain.

With that in mind, you want to think about changing the FillDataSet() method even more:

Public Function FillDataSet(SQL As String, Params parameters() As OleDbParameter) As DataSet
    Dim ds As New DataSet
    ' Rest of the method is here
    Return ds
End Function

Take special note of the second function argument. It is there to avoid SQL Injection problems. It's hard to over-state how important that is.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you Joel! I absolutely know my understanding is not there. It makes it difficult to even figure out how to phrase the question. You are hitting what I was getting at. Your example looks much cleaner than mine. Noted on Injection problems. This is just for me and learning. I'm not loose in the wild, so you can sleep easy.
I added code as requested. I was trying to figure out once the dataset is returned in the Module.Function if there was a way to interact directly with it from the form without another dataset. But I think you're right, if I had a better understanding of the difference between reference, variable, object etc. I would be able to figure it out looking at examples.
The best way to thank someone on Stack Overflow is to accept the answer by clicking the check mark (tick mark) to the left of the answer. You can also upvote the answer with small triangle on top of the number to the left of the answer.
0

First, if someone mentioned Static, then they are most likely a C# developer and really meant Shared. Static is a keyword that both C# and VB have, but the concepts are totally different. The C# static keyword corresponds to the VB keyword Shared. The VB keyword Static refers to a concept that C# simply doesn’t have. By which I mean that it’s impossible to write equivalent code in C#, although you can write code that is functionally equivalent.

Secondly, the FillDatSet as written can NOT be made Shared as it is in a Module, and methods in a Module cannot be shared. If it was in a class, it could be made Shared because it doesn’t use anything outside of the function. As written, it could be turned into a Sub, as there is no reason it needs to return csvDataSet. You pass in a dataset, modify it, and then return the modified dataset. What you need to realize, is that even though you modified it, it is the same dataset. In this case you might think of it as a bucket that is passed in empty and then returned full. But it’s the same bucket that you created before passing it to the FillDataSet function.

if I was doing a code review, I would suggest that you leave it a function, rename it to GetProspectsDS, move the csvDataSet As DataSet into the body of the function as Dim csvDataSet As New DataSet. There’s no reason why you need to pass in an empty bucket when it’s just as easy to create a new bucket. You would then use it as GetProspectsDS.Tables(0).DefaultView

3 Comments

Thank you. I think I better understand. I had read that it could only be shared in a class and what I was reading used the term Static and in the context of what I was reading I took it to mean if I put it in a class I could access the dataset directly without 'recreating the wheel' (so to speak) on the form. I like your solution. I appreciate you and all Joel's help as well. I'm not sure how to give both of you credit for the help. You both have made things clearer for me. I will upvote Joel and give you the answer. If there is a better way, someone can comment at me and I will fix it.
Well. It wouldn't let me upvote Joel's answer because I'm new. I think it deserves credit as it is well explained and useful. Maybe someone here with more cred could give it an upvote for me?
@New2Net: you need another 2 points, if you can find a question or answer where you can do a good edit, that will do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.