Was having a nightmare trying to come up with a title to resume my question.
Anyway, my question is really simple, is it better to do this:
Private TxtbxUserName As New TextBox With {.Text= "XXXX"}
Private Sub DoSomething(ByVal TextBoxText as string)
Dim Text as String = TextBoxText
End Sub
or to do this?:
Private TxtbxUserName As New TextBox With {.Text = "XXXX"}
Private Sub DoSomething()
Dim Text as String = TxtbxUserName.text
End Sub
And what are the specific advantages of each method?
It's hard to say, with such a simplified example, since both options can be preferable, depending on the situation. Generally speaking, though, taking the value as an argument (as in your first example) is preferable to getting the value from the control directly. There are many reasons why, but here are a few that come to mind:
Reusability - You can call the method from anywhere, even if you get the value from a different control, a file, a message, or anywhere else.
Readability - It is easier to follow what the code is doing and why
Testability - It is easier to test the code because you can pass different values into it and test the results without having to touch the UI
As a general rule, you should get the values from the controls as quickly as possible, usually immediately in the control's events, and then pass the values as parameters into the various business methods. If the controls need to be updated with any results, the controls should be set as late as possible. The business methods should return the values rather than setting the values of controls directly.
However, that being said, if you have a method which is entirely, or at least almost entirely, dealing with the UI, it may make sense for it to work with the controls directly. For instance if you are populating a tree control with data from an XML file which defines the node-layout for your UI, it may make sense to access the tree control directly in the method. It wouldn't necessarily make sense to load the data into some sort of tree data-structure just to turn around and read the tree data-structure to populate the tree. It depends. Basically, if it's a UI helper method--something to make it easier to work with a particular control--then it makes sense, sometimes, to have it work with the control directly. Otherwise, if it's a standard business logic method, you'll want to keep UI-related stuff out of it as much as possible.
As well as what Steven Doggart wrote, it could make more sense to use a function:
Private Function DoSomething(ByVal target As Control) As String
Return target.Text
End Function
as then you are not creating side-effects - in the case of your examples the side effect is altering a variable which is outside the scope of your method.
Related
Good day.
Not sure how to word this but please stay with me.
I have several instances of several classes with various properties of various types.
My users (very small business that I work for) would like to perform custom calculations on those variables and display the results in a new DGV column.
For instance
DGV1 uses list(of Myclass) as it's datasource. The columns are automatically added instead of predefined.
One user thinks up a property they would like to always see on dgv1.
He decides that this new property should be the result of
(Myclass.property1 - Myclass.property2)
Iv'e never done this sort of thing and have no clue where to start. I do know that I can't possibly hard code every possible combination of properties. Also, there's know way for the users foresee every combination that they'll need.
It basically needs to be as flexible as excel.
I have a logictree style custom filter builder for queering against properties of theses objects. Some of the users also want to be able to use these custom properties as nodes in the filter.
I'm not even sure if there's a way to add a property to a class at run time and in such a manner that it behaves as properties which are hard coded.
I'd be grateful for your thought and advice on this matter. Also, If I'm unclear on anything then I apologize. Please let me know if I need to clarify something.
Thank you, in advance.
*Edit#
I have discovered Typebuiler and am reading up on it.
There is no real way to add properties to a class on runtime. Once a class is created it's basically set in stone.
You could however have a Dictionary(Of String, Object) to hold the name and value of "properties" in your class. Make all properties like this and you can sort of simulate addable and removable properties. This however is limited to the object.
If you also want your customers to be able to perform calculations, you will have to write a script engine or use one.
I suggest to use a JavaScript engine. With JavaScript you can add properties whenever you want and you have JavaScript as a complete scripting language (JS is not only limited to the web).
I can suggest NiL.JS (https://github.com/nilproject/NiL.JS) as an engine. It is fast and you can easily convert objects back and forth from JS to .Net.
Here is how to use it:
Dim o As New YourCustomObject() ' Your object (e.g. has a property x (double))
o.x = 5.0
Dim c As New Context() ' Create a new JS environment
c.DefineVariable("o").Assign(JSValue.Marshal(o)) ' Transfer the variable
c.Eval("o.x = 6.0;") ' Change the value in JS and it will change in .Net
MsgBox(o.x) ' 6.0
It's a little more difficult to retrieve properties added in JS, but it is possible. I suggest looking at the examples at the GitHub page.
I don't know about the licensing of Nil.JS but there are similar engine out there.
hopefully you can either validate my assumption or point me in the right direction.
I'm working on a small GUI to monitor a variable DC power supply. The equipment communicates via a COM port. To do this I have created a Class to handle communicating with the PSU. I would like to implement a method in which the calling form (class) can pass 2 Label references to my PSU class which it can periodically update with voltage and current.
I have already worked out how to update a Label's text from outside the main thread (with Invoke), and I have worked out how to start a second thread running a method with no parameters. From my reading, I can only pass a single parameter to a parameterized thread start.
My current approach is to create a Collection and have the items be those two labels which I mean to pass. The method to create and start the thread accepts (what I think are) pointers to the two labels with the following:
Public Sub monitor(ByRef vLbl As Label, ByRef aLbl As Label)
Inside that sub (after some error checks and other tasks) I create a new Collection and add the two label references:
Dim coll As Collection = New Collection()
coll.Add(vLbl)
coll.Add(aLbl)
Which I then pass coll in the thread.Start call.
In the sub actually running on the other thread, I start it by breaking out the two labels:
Dim _vLbl As Label = coll(0)
Dim _aLbl As Label = coll(1)
Is this a sound approach to the problem? I realize that I could simplify some of this by eliminating the class approach and taking more of a procedural one, but I'm trying to develop my PSU class reference to be used by some other software tools as a library eventually. Please forgive if I have messed up the terminology, I haven't been doing this for long and am trying to teach myself how all of this works.
Thanks in advance.
Edit: Grammar Fail
For what it's worth, this isn't how I'd do it, as it violates separation of concerns. The code that knows how to read the PSU shouldn't need to know what a label is or how to update it. In the future, you might want to use something other than a label, or may wish to store the numbers in a database as you go, or you might want to use a globalized approach to formatting the number (for example). If you were ever to make those changes, you shouldn't have to touch the PSU code.
Instead, I would create an object, say, PSUMonitor, which does the monitoring. The PSUMonitor would raise an event with a custom EventArgs capable of carrying the data you wish to track.
Then, your UI form would subscribe to those events, read the numbers, and then format the information to put them on a label, two labels, a graph, a table, aor whatever else you want.
This is one of those questions that has been niggling around in the back of my mind since day one of programming in VB in general. I have my own personal ideas about it, but I am wondering what the general consensus is on the use of static variables.
Static Variable:
Public Function Whatever() as Boolean
Static Flag as Boolean
If not Flag then
' do something
Flag = True
end if
Return Something
End sub
VS:
Private Variable:
Private Flag as Boolean
Public Function Whatever() as Boolean
If not Flag then
' do something
Flag = True
end if
Return Something
End sub
Unless someone knows otherwise, the above are functionally equivalent, other than the fact that the "Private" Flag is exposed to be used elsewhere in the class.
Questions begin to arise with Statics.. like..
Where are they stored.. when are they REALLY created and disposed etc.
Obviously, the compiler adds them to the data heap (I know, bad usage of THAT word) for the class somehow... But is there a penalty for that in terms of overhead, garbage collection etc.
Generally I avoid them like the plague because they present more questions than answers.
Is there really any SOLID reason to ever use statics?
PS: Hopefully this passes the SO question test...
Note I am not asking specifics about how statics are created.. I am more asking what if ANYTHING would make using a static worth it.
ADDENDUM....
I did a little more research and found this rather enlightening.
https://weblogs.asp.net/psteele/7717
Is there really any SOLID reason to ever use statics?
Yes. It’s arguably in the first letter of SOLID: S for “single responsibility principle”. In this particular context it’s a slightly different rule:
Objects should have the smallest possible scope.
If an object isn’t needed outside scope X, it should be declared inside scope X. This ensures that it has a single responsibility, and isn’t improperly accessed elsewhere. It also ensures that only one method has the responsibility of accessing this object.
Hence, in your case, the best idea would indeed to make the variable a function-static (= local) variable rather than an object-private variable.
This is indeed fairly uncommon in my experience. But it is best practice.
(In terms of performance/memory these two variants would be exactly identical.)
So from research I have come up with the following.
Static variables are "Lazy" variables, in that they are created when required the first time the function or routine is called. There is an overhead associated with the creation, and more importantly, first initialization in order to make it thread safe.
As Konrad suggests the main reason to use statics is to minimize the scope of the variable to where it is needed.
So... when required
Use SIMPLE static variables (Booleans, Integers etc.) in functions and subroutines that are less commonly used. If you expect the users of the class to ALWAYS call that function, and expect there to be 1,000s of instances of the class... you are adding A LOT of overhead.
Never use static variables of object types that need to be disposed unless you add some functionality (paramaters) to the routine that allow you to call it in a Dispose mode and remember to do so in the classes Dispose function.
Similarily, do not use a static variables as a reference to some other object in your project. Doing so can prevent said object from being garbage collected elsewhere in your code since it is still referenced.
Finally, if you use the Private variable method instead, give it a name that makes it obvious that the variable is being used for that function.. e.g. stat_Half_Time_Score
I run across this problem every time I create a UserControl which displays some data and I need a method that refreshes the data. I like to use simple common names for everything, and follow the principal of least astonishment and have names that are intuitive for others (or me 6 months from now) to understand.
The obvious name for my method would be Refresh, but that's already used by the base class.
I don't want to Override it, because I don't need to refresh my data every time the base class calls this method. Data refresh and screen refresh are just different functions and I don't think they should be mingled.
I don't want to Shadow it either, because I don't want to interfere with it's functioning.
Something I have not learned yet, which to me is interesting, is that if I Overloads it, MyBase.Refresh() takes me to the Object Browser, and Me.Refresh() takes me to my method.
Public Overloads Sub Refresh()
'Code to refresh data
End Sub
Me.Refresh() shows up in the Object Browser under my class, and the Refresh belonging to Control shows up under UserControl. Interesting as I never noticed that before.
I'm not sure if this avoids a collision with the base class in all cases or not! I mean, what about late binding? Like I say, I'm not even sure how the compiler knows them apart, but I can see that it does.
It seems like a neat trick but it would astonish anyone using my control, right? Would that astonish you?
What name is the standard name for such a function?
Better yet, is there a list of vb.net method names that are industry standard for basic common operations?
Minutia:
To nit pick, technically, it's not always a Reload, because I'm not always re-loading all the data; maybe I'm just incrementally syncing it. Load connotes an initial load, not a refresh. Sync is more like it, but this is not the first place most people would look in intellisense for this method, I would think. The name itself should not be astonishing. Update is ambiguous; who is updating who, i.e., which direction is the update going? DataBind is technically incorrect if I'm not actually using data binding or a data source. And any name that I can think of that fits all these criteria may not be in common use - RefreshData, for example. Not to mention, finally, that a one word name would be simpler.
Reload is not so bad. I think a name reload doesn't have to worry about how it's reloaded (sync vs full load).
I work on a class in VBA, that encapsulates downloading stuff with MSXML2.XmlHttp.
There are three possibilities for the return value: Text, XML and Stream.
Should I create a function for each:
aText=myDownloader.TextSynchronous(URL,formData,dlPost,....)
aXml.load myDownloader.XmlSynchronous(URL,formData,dlPost,....)
Or can I just return the XmlHttpObject I created inside the class and then have
aText=myDownloader.Synchronous(URL,formData,dlPost,.....).ResponseText
aXML=myDownloader.Synchronous(URL,formData,dlPost,.....).ResponseXML
In the former case I can set the obj to nothing in the class but have to write several functions that are more or less the same.
In the latter case, I relay on the "garbage collector" but have a leaner class.
Both should work, but which one is better coding style?
In my opinion, the first way is better because you don't expose low level details to a high level of the abstraction.
I did something similar with a web crawler in Java, so I have a class only to manipulate the URL connection getting all the needed data (low level) and a high level class using the low level class that return an object called Page.
You can have a third method that only execute myDownloader.Synchronous(URL,formData,dlPost,.....) and stores the returned object in a private variable and the others method only manipulate this object. This form, you will only open the connection one time.
After much seeking around in the web (triggered by the comment by EmmadKareem) I found this:
First of all, Dont do localObject=Nothing at the end of a method - the variable goes out of scope anyway and is discarded. see this older but enlightening post on msdn
VBA uses reference counting and apart from some older bugs on ADO this seems to work woute well and (as I understand) immediately discards ressources that are not used anymore. So from a performance/memory usage point of view this seems not to be a problem.
As to the coding style: I think the uncomfortable fdeeling I had when I designed this could go away by simply renaming the function to myDownloader.getSyncDLObj(...) or some such.
There seem to be two camps on codestyle. One promotes clean code, which is easy to read, but uses five lines everytime you use it. Its most important prerogative is "every function should do one thing and one thing only. Their approach would probably look something like
myDownloader.URL="..."
myDownloader.method=dlSync
myDownloader.download
aText=myDownloader.getXmlHttpObj.ResponseText
myDownloader.freeResources
and one is OK with the more cluttered, but less lineconsuming
aText=myDownloader.getSyncObj(...).ResponseText
both have their merits both none is wrong, dangerous or frowned upon. As this is a helper class and I use it to remove the inner workings of the xmlhttp from the main code I am more comfortable with the second approach here. (One line for one goal ;)
I would be very interested on anyones take on that matter