Solved

Class Hierarchies

Posted on 2014-03-25
17
29 Views
Last Modified: 2016-06-20
Hi there, I am trying to write a library to use within my applications. I realised that it would be better and would be lot easier to use the library if i divide the class in different modules instead of having all methods, enums, properties in one class. I just wanted to follow Microsoft's pattern e.g. System.Web.UI.WebControls.
I also was looking to write something like Core.SQL.DML and may be Core.SQL.Query below is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;

namespace ASPNetSupportFunctions
{
     public class Core
    {
        const string LIBNAME = "Functions Library";
        public const string SQL_INSERT_FAIL = "ERROR: SQL INSERT FAILED.";
        public const string SQL_UPDATE_FAIL = "ERROR: SQL UPDATE FAILED.";

        // regular expression for email patterns 

         public const string REGEX_EMAIL_PATTERN = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";

        //sql db getdate()

        //static public const string SQL_GETDATE = "getDate()";

        // SQL Server database variable typess

        const string DBType_Int = "int";
        const string DBType_SmallInt = "smallint";
        const string DBType_Decimal = "decimal";
        const string DBType_VarChar = "varchar";
        const string DBType_Char = "char";
        const string DBType_DateTime = "datetime";

        static System.Random ObjRandom = new Random(Convert.ToInt32(System.DateTime.Now.Ticks % System.Int32.MaxValue));

        static public string exceptionMessage;

        #region "Enumerations"

       static public enum ArrayListCompareMode : byte
        {
            added = 0,
            removed = 1
        };

   static public enum ErrorCode : short
        {
            No_Error,
            Object_Reference_Null,
            String_Empty,
            Connection_Not_Opened,
            Different_Array_Lengths,
            Invalid_Content,
            UnExpected_Error,
            Email_Not_Valid,
            Email_No_Subject,
            Email_No_Message
        };

   static public void TestM() { }
        #endregion

        static public bool blnQueryError;
        static public bool blnListControlLock = true; //' addition on deletion of new items forbidden!

        static public int GetRandomNumber(int low = 1, int high = 100)
        {
            // return the number between the optional low and high intgers

            return ObjRandom.Next(low, high + 0);

        }

        static public bool IsDate(string inputDate)
        {
            DateTime dt;
            return DateTime.TryParse(inputDate, out dt);
        }


         public class SQL
        {
              static public string SQL_GETDATE = "getDate()";
             
             static public void GetDate()
             {                  
             }

             static public class DML
             {
                 static public string whatever = "xxx";
             }
             static public class Query
             {
             }
        }


    }
}

Open in new window


The problem is that when i reference my library in another project i can see Core.SQL.DML (or any sub-classes) but i can't see the variable or public method defined in SQL class e.g Core.SQL.GetDate() is not accessible outside the class. I thought it should have been straight forward but stuck from yesterday.

kind regards
0
Comment
Question by:shah36
  • 6
  • 4
  • 4
  • +1
17 Comments
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 39953114
Why are you using nested types for organizational structure rather than namespaces?
0
 

Author Comment

by:shah36
ID: 39953127
Thanks for your comment, actually i have no idea how to do this. I have just started digging into .Net. If you don't mind would you guide me on how to start this?

regards
0
 
LVL 32

Expert Comment

by:Stefan Hoffmann
ID: 39953220
You're mixing here a lot of concepts.

First of all you should watch this video: How To Design A Good API and Why it Matters from Joshua Bloch.

Now for your code:
* Your mixing namespaces and nested classes. Core is normally a namespace, not a class.
* Use at least one file per published type, either class or enum.
* Don't use public const values. In most cases they are part of a class and should be published as a property. Especially when these values are not really a constant or may change due to requirements. E.g. your REGEX_EMAIL_PATTERN is not a global correct regex expression for an e-mail address. See Mail::RFC822::Address: regexp-based address validation for an almost correct one.
* Wrapping functions like IsDate() are dangerous. Especially when wrongly implemented. E.g.
namespace ConsoleApplication4
{
    using System;

    class Program
    {
        static void Main(string[] args)
        {
            string testValue= "";
            testValue = "1900-01-01";
            Console.WriteLine("{0}: {1}", testValue, IsDate(testValue));
            testValue = "01.01.1900";
            Console.WriteLine("{0}: {1}", testValue, IsDate(testValue));
            testValue = "31.12.1900";
            Console.WriteLine("{0}: {1}", testValue, IsDate(testValue));
            testValue = "00:00:01";
            Console.WriteLine("{0}: {1}", testValue, IsDate(testValue));
            Console.ReadKey();
        }
        
        static public bool IsDate(string inputDate)
        {
            DateTime dt;
            return DateTime.TryParse(inputDate, out dt);
        }
    }
}

Open in new window

The last value is clearly not a date.
0
 
LVL 40
ID: 39953232
You do not understand correctly what they do in System.Web.UI.WebControls. Web, UI and WebControls are not classes, they are imbricated namespaces. Think of the whole as subdirectories inside of a root System directory, and the whole as a path to your classes.

If I understand what you are trying to do, you should drop the Core and SQL classes, and make them part of the namespace, by defining the namespace the following way:

namespace ASPNetSupportFunctions.Core
{
        const string LIBNAME = "Functions Library";
        public const string SQL_INSERT_FAIL = "ERROR: SQL INSERT FAILED.";
        public const string SQL_UPDATE_FAIL = "ERROR: SQL UPDATE FAILED.";

        // ..... All your constants, no methods in the namespace itself
             
             public Class SQL
             {  
                 static public string SQL_GETDATE = "getDate()";
             
                 static public void GetDate()
                 {                  
                 }
             }

             static public class DML
             {
                 static public string whatever = "xxx";
             }
             static public class Query
             {
             }
}

Open in new window

0
 

Author Comment

by:shah36
ID: 39953428
Hi JamesBurger,

thanks for your reply as per your suggestion when i try to create namesapce it gives the error message on every type e.g const, string, bool etc and says that A namespace can't directly contain members such as fields or methods.

Please help.
0
 
LVL 40
ID: 39953472
Sorry, I did not notice them.

A namespace is a container for classes, it cannot contain variables and methods that need to be in classes.

So, stuff such as
static System.Random ObjRandom = new Random(Convert.ToInt32(System.DateTime.Now.Ticks % System.Int32.MaxValue));

static public string exceptionMessage;

Open in new window

and
static public void TestM() { }

Open in new window

must be moved inside of your classes. It's up to you to decide in wich classes you include them.

You might want to make Core a class instead of a part of the namespace. But then, it should be at the same level as SQL and DML, not include them as you did in your original code.
0
 
LVL 32

Expert Comment

by:Stefan Hoffmann
ID: 39953536
Just an addendum to public const values: Also think about the usage. E.g. SQL_INSERT_FAIL is a resource.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 39953554
@ste5an

You may want to clarify what you mean by "resource". I know what you are referring to, but shah36 may not.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 32

Expert Comment

by:Stefan Hoffmann
ID: 39953569
0
 

Author Comment

by:shah36
ID: 39953739
Well I have just discovered that if i reference the library to web, windows or WPF application all the methods and variable in all classes including the nested are accessible but if i reference my library to another class library (which is my requirement) the methods and const of the classes are not accessible but only nested classes are accessible.  

This seems bizarre
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 39953747
Do you understand the difference between static and instance members?
0
 

Author Comment

by:shah36
ID: 39953896
Sorry if i am wrong here But the static members have only one copy in memory while the instance members will have multiple copies when they are referred to.

For example the constructor provides us the facility to instantiate a class and it will create a new object of that class type in memory and we can access the non-static properties and methods of the class by instantiating the class.

 however as the static members can't be accessed by an instance of class because they are not instantiated with the new object of that class type
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 39954073
Almost entirely correct. The only issue is your last paragraph. Static members *can* be access by instance members--not the other way around. This is because static members are deemed to be related to the class, but not to any particular instance. Since a static member is not related to any particular instance, it cannot see any instance members.

The programmatic implication is that when you want to refer to a static member, you have to use the class name, not the name of an instance variable, when you want to refer to the static member. My concern now with you not being able to see the various members is whether or not you are properly referencing each type of member. If you are trying to use static members, then you should be using the class name (e.g. ClassName.StaticMember()); if you are trying to use instance members, then you should working against an instance of the class (e.g.  (new ClassName()).InstanceMember())
0
 

Author Comment

by:shah36
ID: 39954535
Thanks for testing purposes i have created a class library supadupa, created the dll and referenced the dll in web application and another class library project.

Web Application screen shot

as you can see here that the fields and methods of the nested SQL class are visible in asp.net application

Dll in ASP.Net application
Here only the nested classes of SQL Class are visible and other methods and fields are not

Class Library screen shot
Reference in class library
0
 

Accepted Solution

by:
shah36 earned 0 total points
ID: 39993768
Well in my methods i changed from
static public to
public static

and now i can access my methods of a class library in another class library.
0
 
LVL 32

Expert Comment

by:Stefan Hoffmann
ID: 41662142
As there is no difference between "static public" and "public static", it's not the answer. The C# language specification does not require an specific order of class modifiers.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now