VB.NET Class Generation

  • Thread starter Thread starter Richard Brown
  • Start date Start date
R

Richard Brown

Ok, now I am truely going nuts... probably why I didn't use the Class
Builder in VB6 extensively.

But, being the 'proper programmer' that I should, I'm trying to bite the
bullet and build classes for each of my 'entities' that operate within the
program, ie, passenger, vehicle, etc. Then seperate UI classes that link to
these. (Partially, because eventually several add-ons will be able to reuse
the code in the data classes).

My question is this....

Is there any SHORTER way to define properties in a class than....

Public Class Passenger
Private sFirstName As String

Public Property FirstName As String
Get
FirstName = iFirstName
End Get
Set
iFirstName = FirstName
End Set
End Property
...
End Class

Obviously, with 10-20 fields in the class, you end up with, oh 100 lines of
code... doing not much more than setting and retrieving variables. Which,
if that was the case, would be fine, but I'd also like to set a 'dirty' flag
if any of them are reset, some business logic will be in some fields, etc.

So, is there a 'short-form' for properties, OR, is there a way to 'fake'
properties, that is something to do with the reflection library to simulate
properties, but have them all serviced by only a couple property functions
(ie, use a collection to store the values, and one property service function
to check them/assign them/perform other logic).

This probably sounds lazy of me, but Im dreading going through and creating
20-30 data class libraries with 20-30 fields each ---- just tell me it isn't
so.
 
Nope, there's really isn't a shorter way.

The only "shortcut" is to expose public fields:

Public Class Passenger
Public FirstName as String
End Class

If you do this, you can treat it like a de facto property. However, this is
frowned upon in OO programming -- you can't insert code to validate the the
property, unless you change the field to a property. But, for a contrary
perspective, check out the "which is faster, Public Field or Property"
thread in microsoft.public.framework.performance.
 
Thanks Robert,

Yes, I have looked at the thread in the performance newsgroup, very
interesting and am following it.
I got creative and started looking into the Reflection.Emit library and
dynamic assemblies and such...
Was just wondering if there was a way to use Reflection.Emit to alter an
already defined assembly on the fly, ie, use BuildProperty interfaces to add
dynamic properties to the class I have already created....

I know... I really like pain.... a lot of pain...
 
Hi Richard,

|| I know... I really like pain.... a lot of pain...

LOL.

You mentioned the VB6 Class builder. You can get class builders for .NET,
I'm sure, though I've never used one. Perhaps a Google search?

Another approach is to write your own Property Generator using macros
(Tools/Macros). The full method is to write an Add-In, but a quicker way is to
write a macro which you can assign to a key. Press the key and your code
sticks up a dialogue with a TextBox for Name, Checkboxes for Get/Set,
DirtyBit, etc. Hit Ok and it inserts the Property into the current code module
at the current position.

I'd love to give you a sample but I'm busy right now (zzzz). Perhaps you'd
like to specify what you want. I'll look at it tomorrow and turn over my
findings to you. You can take it from there.

Regards,
Fergus
 
Ditto on the LOL. <g>

I'm sure there are templates/code generators out there to ease the pain. As
an alternative, you could try writing a macro to automatically insert the
property declarations. Using reflection is _really_ the hard way to go.

If you're concerned about the ugliness of your code, remember that #Region
is your friend.

(I.e.,
#Region " Stupid Property Declarations "
....
#End Region
)

Just remember... was it really any better in VB6?
 
Hi Richard

I'm not sure why you find this so annoying?

But as you do I thought I'd share an idea I had as I get a
bit fed up replicating database structures into object
models. I haven't actually implemented this yet (but I
plan to) so it may not work for some reason I haven't
thought of.

In ADO.NET the dataset class would seem to provide
everything you need. Primarily, it's only connected to
the database whilst the data is being retrieved or updated
so I can't see a problem with having one alive for an
extended period of time. Also if you change the values of
any fields the original values are preserved so you can
provide an Undo facility. IsDirty properties can be
implemented by comparing the old and new values. Finally
all of the database rules such as datatypes, uniqueness
and relationships are part of the dataset so you can use
those as a basis of your validation and if the database
changes so does your application without having to re-
compile it.

Last thing is that the Dataset class is inheritable so you
should be able to derive custom classes to suit your needs
eg add a readonly property for FullName that concatenates
FirstName & " " & LastName.

OK, really last thing is there is a ms supplied console
tool for creating your own strongly typed datasets called
xsd which makes your code nicer.

I guess this is a bit more than you were asking for, sorry
if I've gone off on a bit of a tangent?

Eric
 
Richard,
Instead of Reflection.Emit consider using the System.CodeDom namespace.

Reflection.Emit creates binary assemblies, System.CodeDom creates text
source files.

There is also using Macros and actually inserting text into the current
document.

If I have the 'definitions' in a database/text file/xml file I've been known
to use System.CodeDom to create the skeletons for my class, then modify that
to complete it.

Hope this helps
Jay
 
I'm a long time VB programmer but am brand new to .Net. I'm suprised
that VS doesn't include a 'Property Builder' and would like to create
one for myself. I'll probably wind up doing it as an add-in but I'm
curious about how to open a dialog box from a macro. Is that possible?

Thanks,

Don
 
Hi Don,

It certainly is. :-)

You've got access to the simple built-in ones - InputBox()

You can also create your own forms. Although the Macros IDE only gives you
the choice of Add Module, Class or Code File, a Form is a Class so you can
create a form that way. It's easier though, to create the form in the regular
IDE and the use Add an Existing Item.

You'll probably have to add a few References to the project.
System.Drawing wasn't there by default in my setup (v2002).

Regards,
Fergus
 
Hi Fergus, thanks for your help.

I created a smal test project with a simple dialog box to make sure it
worked. It did.

I then created a test macro and added the dialog box as an 'Existing
Item' and tried calling it the same way that I did in my test project.
When I run the macro (code below) I get a build error on the 2
'DialogResult' lines:

Name 'DialogResult' is not declared.

That looks like the missing 'User Defined Type Declaration' error that
you get in OLD VB when when a Reference is missing.

I found 'DialogResult' in 'Help' but don't see anything that indicates
what Reference is needed. Learning all these Namespaces, assemblies,
components, etc. seems pretty daunting so any tips on navigating this
stuff will be greatly appreciated,

Sub TempMacro1()
Dim dialog As New MyDialog1
Select Case dialog.ShowDialog()
Case DialogResult.OK
'-- the Ok button was pressed
MsgBox(dialog.txtPropName.Text, MsgBoxStyle.Information)
Case DialogResult.Cancel
'-- the Cancel button was pressed
MsgBox("Cancel was pressed.", MsgBoxStyle.Exclamation)
End Select
dialog.Dispose()
End Sub
 
Hi Don,

If you have the .NET help, look up DialogResult in the index. You'll see
DialogResult enumeration and DialogResult property. The latter is the result
from the Form, which you know about. The enumeration is the one that you are
using in your Case statements and having trouble with.

Click on that the enumeration entry. This will take you to the page giving
that familiar list of Ok, Cancel, etc.The bit you're interested in is at the
bottom where it says Requirements. Under that it says the Namespace that you
need in order to reference the item in question. For DialogResult it's
System.Windows.Forms.

Now you have a choice. You can either give the full name each time you use
DialogResult or you can add an Imports at the top of the code.

Case System.Windows.Forms.DialogResult.Ok
Case System.Windows.Forms.DialogResult.Cancel
or
Imports System.Windows.Forms
: : :
: : :
Case DialogResult.Ok
Case DialogResult.Cancel

I know which I prefer. ;-)

Regards,
Fergus
 
Fergus,
Which one?
I use them in a way like one time using no import; more times using,
import.
Except with "mshtml" that I never import anymore.
Cor
 
Howdy Fergus, thanks for sticking with me long enough for this stuff
to begin seeping through my thick, boney skull.

I did have a Reference to System.Windows.Forms but, as you pointed
out, I didn't fully qualify the name\path to DialogResult.

To help solidify this stuff in my brain, I've tried it both with the
Imports statement and the old VB way by dimming an object variable of
type System.Windows.Forms.DialogResult

Dim diagResult As System.Windows.Forms.DialogResult
Select Case dialog.ShowDialog()
Case diagResult.OK
Case diagResult.Cancel

I guess the Imports statement is better. I messed around with Delphi a
couple years ago and remember that it uses a similar method. Instead
of 'Imports' Delphi has a 'Uses' statement. I didn't use Delphi enough
to get really familliar with it but I can see that VB.Net looks a lot
like it.

I just installed .Net a couple days ago but I downloaded the free pdf
book that MS made available when they first released the .Net beta.
"A Programmer’s Introduction to Visual Basic.NET" by Craig Utley. It's
been very helpful and I've seen very little diference between the beta
and the VS,Net 2003 Pro version that I just installed. I have no
problem understanding what I've read in the book but simply
understanding is not knowing.

Thanks again, you've been very helpful.

Don
Redmond, WA
 
Howdy Don,

|| Dim diagResult As System.....DialogResult
|| Select Case dialog.ShowDialog()
|| Case diagResult.OK
|| Case diagResult.Cancel

That works fine as you found. You could also have used the Form's
DialogResult.

Select Case dialog.ShowDialog()
Case dialog.DialogResult.OK
Case dialog.DialogResult.Cancel

because, like diagResult it has access to its class' contants. but it
looks a bit confusing that way.


|| Delphi has a 'Uses'

And C# has "using" which I prefer over Imports.


|| I just installed .Net a couple days ago ...

Two days in and you're getting into interactive Macros, and then on your
way into Add-In territory. You're an intrepid explorer - I'm proud of you.
:-))

All the best,
Fergus
MVP [Windows Start button, Shutdown dialogue]
 
|| I just installed .Net a couple days ago ...

Two days in and you're getting into interactive Macros, and then on your
way into Add-In territory. You're an intrepid explorer - I'm proud of you.
:-))

All the best,
Fergus
MVP [Windows Start button, Shutdown dialogue]

I lied. I installed it last Friday so it's been almost a week now. <g>

Thanks again,

Don
Redmond, WA
 
Back
Top