Structuring Class with constructor - asp.net

I have a Class with a Constructor. My constructor takses all the required parameter, then I use the parameters to return another class.
Public Class SearchResults()
private id as int
Sub New(id) ' Constructor
getResults(id)
End Sub
Public Function getResults(byval id as int) as List(of Products)
........
return list (of products)
End Function
End
Then in my page I want to get all the productts.
Dim s = new SearchResults( 1 )
Dim p as list(of Products) = s.getResults()
----now I can do for Each on this
This works for me, but I do have a feeling there has to be a better way of doing it, I want to stick to the best standards. do you guys think, this is the best approach or it could be improved? My designers will be utilizing this class within their projects...so i would love to make it as simple as possible for them.
or maybe how to create an Collection of a Class...for example Class Product and its collection Class Products, Where Products is the Collection of Project Class.

There are three ways to do what you want:
1) You can load the results and store them in the object on the constructor
2) You can store the ID in the object and call the function to get the results when needed
3) You can make the function static and pass in the ID as well as the collection (or resource needed to get the collection) and not use an object at all.
Depending on what you need, most likely either 1 or 3 are going to be best. If you plan on reusing the object for other methods than just the one function, then option 1 is the best, but if you just need the 1 function, go with option 3 like this:
Public Class SearchResults
Public Static Function getResults(ByVal id As int) As List(Of Products)
'........
return list (of products)
End Function
End Class

You could make the getResults method static possibly and cut out having to create a class instance to call it.

I personally would declare the getResults method as Shared so that you don't have to create a SearchResults object just to access that method. This would also allow you to call the method again with another ID without having to create another object.

Related

asp.net VB best way to return result code

For asp.net framework 4.5 vb
I know that I can use a session variable.. but wondering if there is a more efficient way to return a variable (we call it a condition code) that we set almost in every function /sub being called.
Example
Function xyz(bla as String, blab as String) as dataset
.. do the deed
**Cond.code = -1**
Return ds
We use this Cond.code everywhere. Obviously it can not be a Public Shared variable... but want the most efficient way to always set a "condtion code" within any sub or function... It is valid, only from the time it is set, to the time it is checked by the calling function... so the lifetime is very short.
It's unclear what, exactly the condition code is used for. It's possible that a proper use of custom exception types would replace the need for it. However, if you really need it, it would be better to have it be returned by the method, rather than essentially setting a global, which is pretty rotten. What happens if two methods ever got called simultaneously? It's just brittle and unnecessarily confining.
For instance, you could make a container to hold the return value plus the condition code, like this:
Public Class ReturnValue(Of T)
Public Sub New(value As T, conditionCode As Integer)
Me.Value = value
Me.ConditionCode = conditionCode
End Sub
Public ReadOnly Property Value As T
Public ReadOnly ConditionCode As Integer
End Class
By requiring the code in the constructor, like that, it forces every method to always specify a condition code in its return value. That way it could never be forgotten:
Function xyz(bla As String, blab As String) As ReturnValue(Of DataSet)
' do the deed
Return New ReturnValue(ds, -1)
End Function
However, even then, I would still strongly recommend making the condition code use an enumeration or, at the very least, a set of constants. -1 isn't very self documenting.

Newbie to using Classes Properly - How to Set a Property or Class Value to return of a Function

I have been building various web based programs and things for a while, but am quite new to .NET and doing things "properly." As I am completely self taught, with help from sites like this and so on, my understanding of fundamentals is limited.
So, I have a series of functions which return data that I want depending on parameters put in, this is very basic stuff, and obviously all works. However, I am trying to make it easier to call these functions by using Classes.
So, say I have a function which returns a populated DropDownList converted to an HTML string
Function GetList(ListRequired as String) as String
' Do stuff to return a dropdownlist whos contend is determined by `ListRequired`, converted to an HTML string
End Function
In this example, it works fine, but to use it I must know what to enter for "ListRequired" to get what I want.
So, let's say, the options for the ListRequired para are "mastercategory", "brandlist", "priceranges" to return a different set of lists - each option would send the code off the retrieve information from a database and return accordingly.
Suppose I want a third party developer to be able to call this function with the most basic amount of "instruction" required, and not even have to tell him the list of available ListRequired by making it available as a Class.
Public Class DropDownLists
Public Property MasterCategory
Public Property BrandList
Sub New()
Me.MasterCategory = HTMLControls.RenderSearchFilters("mastercategory")
Me.BrandList = HTMLControls.RenderSearchFilters("brandList")
End Sub
End Class
A developer can then call this from Visual Studio/VWD etc very simply:
Dim dd As New DropDownLists
Dim list1Html as String = dd.MasterCategory
Dim list2Html as String = dd.BrandList
Because VWD etc creates all the handy helpers and displays which properties the Class exposes, it is very easy to use this code without have to constantly refer to a manual.
However... when creating a new instance of the Class:
Dim dd As New DropDownLists
This will cause the server to process all the functions within the class which create the Properties, which would be desperately inefficient if there are lots of properties.
So I have tried using my own interpretation of the logic and written this:
Public Class DropDownLists
Shared Property Master
Shared Property Brand
Sub New()
End Sub
Public Class MasterCategory
Sub New()
DropDownLists.Master = HTMLControls.RenderSearchFilters("mastercategory")
End Sub
End Class
Public Class BrandList
Sub New()
DropDownLists.Brand = HTMLControls.RenderSearchFilters("brandList")
End Sub
End Class
End Class
Hoping I'd be able to create the HTML for a Master Category drop down like:
Dim dd as New DropDownLists.MasterCategory
But that doesn't work, and upon reflection I think I can see why... it's not returning the string, but creating a new type.
So... my question is...
What is the correct way to achieve what I am looking for, which is, to be able to create these string outputs by typing
Dim dd As New DropDownLists
Dim list1Html as String = dd.MasterCategory
Dim list2Html as String = dd.BrandList
Without having to pass potentially unknown string parameters, or causing ALL properties to be created each time the DropDownLists Class is created, ie, only run the code for the output I need.
I'm expanding my comment to give you a clearer idea of what I meant:
Public Class DropDownLists
Enum ListType
Undefined
MasterCategory
Brandlist
End Enum
Public Shared Function GetList(ListRequired As ListType) As String
Select Case ListRequired
Case ListType.Brandlist
Return . . .
Case ListType.MasterCategory
Return . . .
Case ListType.Undefined
Throw New . . . .
End Select
End Function
End Class

How does a class member gets updated automatically in a Sub routine / function even if I pass in ByVal in VB.NET?

Can anyone help explain why the following will change a value in an object's member even if I pass it in ByVal?
Scenario: The name of the person is 'Sab' but when i pass the object in the sub routine, the name changes to 'John'.
I thought object types are passed in by reference only and should not be changed unless forced. Is this a feature in .NET and what is this behavior called?
Sub Main()
Dim p As New Person
p.name = "Sab"
DoSomething(p)
Console.WriteLine(p.name) ' John
Console.Read()
End Sub
Public Sub DoSomething(ByVal p As Person)
p.name = "John"
End Sub
Writing to p.name is not the same as writing to p. ByVal prevents the parameter itself from being modified, e.g.
p = New Person
If you want to prevent the properties of Person from being written to, then you need to re-design the Person class to be immutable instead of mutable. Whether this is an appropriate thing to do depends on how you want your code to behave.
Example:
Public Class Person
' All fields are private
Private _name As String
' All properties are read only
Public ReadOnly Property Name As String
Get
Return _name
End Get
End Property
' Field values can *only* be set in the constructor
Public Sub New(name As String)
_name = name
End Sub
End Class
An instance of an object is a reference - it's a pointer to the object. If you pass any object by value, you are passing it's reference by value. Effectively, there is no difference in passing an object by value or by reference. .Net creates a new copy of the reference and passes it's value to your method but the new copy of the reference still points to the same object. Some folks say that "all objects are passed by reference" but this is not true, the reference to the object in the called method is NOT the same as the reference in the caller but they point to the same object.
If you really want to pass a copy of the object such that the called method may not modify the originals' properties, then you need to create a copy. See discussions about shallow vs deep copies and be careful to understand references to objects vs simple data types. Do think about your design though. It's rare to actually need to create a copy rather than a new object.

Not able to access class level private variables from different methods/functions of the same class

In the following I am trying to define a Private variable on Class level called _p. The HTTP.POST for Index will bring a User provided value which I'll set this private variable with. In the second Method called ListOfVehicles, I'll be accessing this variable.
Now everything is alright theoretically, however when I try to access this private variable I don't get anything, this is found Nothing.
Public Class QuotationController
Inherits System.Web.Mvc.Controller
'Private Variables
Dim _p As String
'Get Basic pickup and dropoff details
Function Index() As ActionResult
Return View()
End Function
'Function to get basic details out of the view
'and to redirect to ListOfVehicles
<HttpPost()>
Function Index(ByVal P As String, ByVal D As String) As ActionResult
_p = P
Return RedirectToAction("ListOfVehicles")
End Function
'Show list of vehicels
Function ListofVehicles() As ActionResult
ViewData("UserChoice") = "Pickup: " & _p
vehicleList = QB.GetQuotation(_p, _d)
Return View(vehicleList)
End Function
End Class
That is fundamentally impossible.
Each HTTP request gets a separate controller instance; they don't share anything.
You should use cookies, session, application state, or cache, as appropriate.
In your case, you should probably include that variable in a POST to the other action from a <form>.
If you don't want to add a formal post parameter you can use
TempData.Add("P", P);
just before the return statement, in your ListOfVeicles you can accesso via
string p = TempData["P"];
Temp data is valid just within the request scope
EDIT: sorry for C# syntax, I'm not using VB since the good old days ov VB 6

asp.net - passing generic lists

I have a utility class that takes a generic list as a parameter.
Code looks like:
Function DoStuff(collection as Object, elt as Object)
...
collection.Add(elt)
...
End Function
This is called with:
DoStuff( List(Of Foo), new Foo() )
DoStuff( List(Of Bar), new Bar() )
There are about a dozen different types.
Currently, passing as Object results in a Late bound resolution warning, although it runs fine.
I've tried different ways to pass in collection and elt (Foo and Bar both extend a base class) but can't seem to figure out the "proper" way to do it.
Ideas?
I think you're looking for something like this.
Public Sub DoStuff(Of T)(collection As List(Of T), elt As T)
...
collection.Add(elt)
...
End Function
The answers by womp and Qua are I think the correct ones, however if your 12 types all inherit from some common base class (as your original question suggests) you can write the method such that it works with your types, and only your types as such:
Public Sub DoStuff(Of T As YourBaseClass)(collection As List(Of T), elt As T)
...
collection.Add(elt)
...
End Sub
This way the method works only for types which inherit from YourBaseClass.
You should always strive to built/use strongly typed code. Imagine what would happen if an integer was passed as the collection object - You would have to manually check for the type of the variable. Even worse though, the user of your method would have to look up in the documentation what kind of object your method required as it's first parameter.
You should go by the approach suggested by womp, or even better you should make your parameter require an object that extends the generic collection interface, ICollection(Of T):
Public Function DoStuff(Of T)(collection As ICollection(Of T), elt As T) As stuff
...
collection.Add(elt)
...
End Function
since this would allow the user of the method to pass not only lists, but also all other classes that inheritage the ICollection(Of T) interface (synchronizedCollection, HashSet, LinkedList, or custom classes ect.) which is really the power of OO programming.

Resources