Results 1 to 5 of 5

Thread: Classes & Class Libraries: Best practices and other imponderables.

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jun 2018
    Posts
    80

    Classes & Class Libraries: Best practices and other imponderables.

    This thread has for goal to gather the POV and experience of fellow VB.NET programmers regarding the creation of Classes and Class Libraries.
    Any questions on the subject or links to documentation are welcome as long as it follows the forum's rules of course.

    I'll start with a question that may seem simple to many but I still haven't found an answer to.
    Assuming I am to create a Class Library for geometrical shapes and I want to store Pi as a constant which of the following would be best:
    Name:  ClassLibraries&Constants.jpg
Views: 417
Size:  27.2 KB

    Jokes aside I highly prefer the first option to avoid calling unrequired classes everytime but I'm not sure my approach would be well viewed.
    Last edited by KBConsole; Jun 24th, 2020 at 01:04 PM.

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Classes & Class Libraries: Best practices and other imponderables.

    Given that there's already a Math.Pi constant defined in the .NET Framework, defining your own would be fairly pointless. If you really wanted to though, you could use that that existing one as an example of how to do it. As the .NET Framework is mostly written in C#, so is that constant. Math is a static class and Pi is a constant declared in that class. That Math class contains members relating specifically to mathematical operations. The VB equivalent of a static class is a module.

    On another note, don't declare one type inside another as a general rule. That applies to classes, structures, enumerations and delegates. Each type should be declared independently unless it will only be used within another type, in which case the inner type should be private anyway. You can declare a nested type and Microsoft used to nest closely associated types, e.g. ListViewItem.ListViewSubItem but they haven't done that for a long time and you shouldn't either. Generally speaking, I would suggest that classes, modules and structures all get there own code file. I tend to use a single code file for all enumerations and all delegates but I wouldn't fault anyone for having separate files for enumerations too. You generally don't need to declare your own delegates so that's rarely an issue (just use Action or Func in most cases) but they are one line each, so a single code file makes sense for all of them.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Jun 2018
    Posts
    80

    Re: Classes & Class Libraries: Best practices and other imponderables.

    Given that there's already a Math.Pi constant defined in the .NET Framework, defining your own would be fairly pointless. If you really wanted to though, you could use that that existing one as an example of how to do it. As the .NET Framework is mostly written in C#, so is that constant. Math is a static class and Pi is a constant declared in that class. That Math class contains members relating specifically to mathematical operations. The VB equivalent of a static class is a module.
    So the Math Class (assuming it was made in VB and not C#) is basically a Module that contains the constants PI and E as well as some functions to do operations on numeric data types ?

    On another note, don't declare one type inside another as a general rule. That applies to classes, structures, enumerations and delegates. Each type should be declared independently unless it will only be used within another type, in which case the inner type should be private anyway.
    Neat so going for the first approach is indeed the best choice then, except my example of creating a Module for the PI constant isn't very useful since that's already a Module in .NET

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Jun 2018
    Posts
    80

    Re: Classes & Class Libraries: Best practices and other imponderables.

    Here's another question while at it; What are the differences/advantages between these two examples:
    vb.net Code:
    1. Public Class SystemUser
    2.         Dim su_Username As String
    3.         Public Property Username As String
    4.             Get
    5.                 Return su_Username
    6.             End Get
    7.             Set(ByVal new_Username As String)
    8.                 su_Username = new_Username
    9.             End Set
    10.         End Property
    11.     End Class
    vb.net Code:
    1. Public Class SystemUser
    2.         Dim su_Username As String
    3.         Public Property Username As String
    4.             Get
    5.                 Dim x as String = su_Username
    6.                 Return x
    7.             End Get
    8.             Set(ByVal new_Username As String)
    9.                 su_Username = new_Username
    10.             End Set
    11.         End Property
    12.     End Class

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: Classes & Class Libraries: Best practices and other imponderables.

    There is NO advantage to the second version. There may be no disadvantage, either. All it does is creates a local variable, then throw it away. That's insignificant, but there's no benefit to it, so why bother?

    I don't like any of the three alternatives to start with. Also, I've done almost exactly that for a project. What I started out with was that there was a common dll that held a base Shape class. This was a pure virtual class (MustInherit) as there were methods like Volume that returned a value, but for which there is no definition for the base class. The derived classes were in different dlls. They referenced that common dll, and inherited from the base Shape class, adding actual definitions for methods like Volume. This was done for extensibility. New shapes could be defined in new dlls, but ultimately, I abandoned this approach.

    What I ended up doing was creating an IShape interface in the common dll. The base class went away. Every specific shape in any other dll (there could be more than one in each dll) implemented the IShape interface, which meant that they had those common methods, such as Volume. The implementation of the methods for each class was different, but anybody could use the IShape interface and call the Volume method knowing that they'd get whatever implementation of that method was right for that class.

    The reason I did this was primarily due to the fact that they had to be able to draw themselves on the screen. The base class tied them to one technology (XNA), which was a limitation. By going with the interface, I could just have a Draw method. If the underlying class used XNA, that was fine. If they use WPF, that will be fine, too. This means that I can switch technology more easily.

    However, once you go to interfaces, you start to find more and more advantages to them. For example, I can create a dummy IShape very quickly, which is convenient for unit testing. I can also make radically different things that implement the IShape. Using the base class, I could only flex as much as the base class allowed. If the base class implemented some method, and didn't leave it up to the derived classes, then any derived class was stuck with the base class implementation (though it could override it). By switching to IShape, the implementation behind anything is as versatile as I can think of.
    My usual boring signature: Nothing

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width