#726 – Listing all Types within a Namespace

You can’t directly list out all types within a namespace.  But you can get all types within a particular assembly and then filter out only the types that match a particular namespace.

        static void Main()
        {
            // Dump all types from in a specified namespace
            DumpTypesForNamespace(Assembly.GetExecutingAssembly(), "ConsoleApplication1");
            DumpTypesForNamespace(Assembly.GetExecutingAssembly(), "ConsoleApplication1.Dog");

            int i = 1;
        }

        private static void DumpTypesForNamespace (Assembly assem, string theNamespace)
        {
            Console.WriteLine(string.Format("[{0}]", theNamespace));

            foreach (Type t in assem.GetTypes())
            {
                if (t.Namespace == theNamespace)
                {
                    string dump =
                        string.Format("{0}\n  ({1} in {2})\n", t.FullName, TypeIndicator(t), t.Namespace);

                    Console.WriteLine(dump);
                }
            }
            Console.WriteLine("\n");
        }

        private static string TypeIndicator(Type t)
        {
            string typeIndicator = "?";

            if ((t.BaseType != null) &&
                (t.BaseType.FullName == "System.MulticastDelegate"))
                typeIndicator = "delegate";

            else if (t.IsClass)
            {
                if (t.IsNested)
                    typeIndicator = "Nested class";
                else
                    typeIndicator = "class";
            }
            else if (t.IsInterface)
                typeIndicator = "interface";

            else if (t.IsValueType)
                typeIndicator = "struct";

            else if (t.IsEnum)
                typeIndicator = "enum";

            return typeIndicator;
        }

726-002

Advertisements

#725 – Dumping Out a List of Types in an Assembly

You can use reflection to get a list of all types in an assembly.  Each type is represented by an instance of the Type class, which you can then query to get information about the type.

Below is a code sample that dumps out all types defined in the running assembly.  Notice that we identify each type as one of the five custom types that you can define.

        static void Main()
        {
            foreach (Type t in Assembly.GetExecutingAssembly().GetTypes())
            {
                string dump =
                    string.Format("{0}\n  ({1} in {2})\n", t.FullName, TypeIndicator(t), t.Namespace);

                Console.WriteLine(dump);
            }
        }

        private static string TypeIndicator(Type t)
        {
            string typeIndicator = "?";

            if ((t.BaseType != null) &&
                (t.BaseType.FullName == "System.MulticastDelegate"))
                typeIndicator = "delegate";

            else if (t.IsClass)
            {
                if (t.IsNested)
                    typeIndicator = "Nested class";
                else
                    typeIndicator = "class";
            }
            else if (t.IsInterface)
                typeIndicator = "interface";

            else if (t.IsValueType)
                typeIndicator = "struct";

            else if (t.IsEnum)
                typeIndicator = "enum";

            return typeIndicator;
        }

#724 – Fully Qualified Names for Types

Every type in C# has a fully qualified name that consists of:

  • Dotted notation indicating the namespace hierarchy in which the type appears
  • Dotted notation indicating the type hierarchy, if the the type is nested

In the example below, the fully qualified name for the DogCollar type would be DogLibrary.MainTypes.Dog.DogCollar.

namespace DogLibrary
{
    namespace MainTypes
    {
        public class Dog
        {
            public class DogCollar
            {
            }
        }
    }
}

You can always refer to a type using its fully qualified name. For example:

            DogLibrary.MainTypes.Dog.DogCollar dc = new DogLibrary.MainTypes.Dog.DogCollar();

#723 – New Methods in Subclass May Not Be Visible in Derived Classes

You can use the new keyword in a subclass to hide a method in the parent class.  The new implementation of the method will now be used in the context of the subclass.

If you call this method in a subclass of the subclass, however, the method called depends on the accessibility of the new method.  If the new method is private, it is not visible in the lowest level class and so the original member in the base class is called.

    public class Dog
    {
        public void Bark()
        {
            Console.WriteLine("Dog: Woof");
        }
    }

    public class Terrier : Dog
    {
        public void DoBark()
        {
            Bark();
        }

        private new void Bark()
        {
            Console.WriteLine("Terrier: Woof");
        }
    }

    public class Yorkshire : Terrier
    {
        public void DoBark()
        {
            // Dog.Bark is called
            Bark();
        }
    }

 

            Dog d = new Dog();
            d.Bark();

            Terrier t = new Terrier();
            t.DoBark();

            Yorkshire y = new Yorkshire();
            y.DoBark();

#722 – Local Variable Declarations May Not Always Hide Class Members

A local variable declaration in a method may hide a class member in the containing class, if the two names are the same.  In general, a declaration within an inner scope may hide a member within the outer (containing) scope.

A inner declaration might not hide an outer member, however, if one of the names can be invoked (e.g. a method) and one cannot be invoked (e.g. a variable declaration).

In the example below, the local variable Name in the inner scope does not hide the method Name in the outer scope.

    public class Dog
    {
        public string MyName { get; set; }

        public void Name(string name)
        {
            MyName = name;

            Console.WriteLine(string.Format("New name is {0}", MyName));
        }

        public void Bark()
        {
            // Local variable does not hide Dog.Name method
            string Name = "Franklin Roosevelt";

            Console.WriteLine(Name);

            this.Name("Bob");
        }
    }

#721 – Local Variable Declarations Can Hide Class Members

It’s possible to declare a variable in a method that has the same name as one of the class members in the class where the method is defined.  The local variable is said to hide the class member.

    public class Dog
    {
        public string Name { get; set; }

        public Dog(string name)
        {
            Name = name;
        }

        public void Bark()
        {
            // Local variable Hides Dog's Name property
            string Name = "Franklin Roosevelt";

            Console.WriteLine(string.Format("{0} says WOOF", Name));

            // Can still access Dog.Name via this pointer
            Console.WriteLine(string.Format("I'm {0}", this.Name));
        }
    }


Notice that you can still access the class-level Name property by using the this keyword.

While it’s possible to hide a class member in this way, it’s generally considered to be bad practice.  When you make Name mean different things, depending on what part of the code you’re in, this can lead to confusion.

#720 – Location of Declarations within A Method Does Matter

When declaring members in a class, you can declare the members anywhere in the class, even placing a declaration after some code that references the declared member.

When you declare variables within a method, however, a variable must be declared before it is used.  Compiling the code below will result in a compile-time error, since the leadin variable in the method RevealNames is declared after it is used.

    public class Dog
    {
        public string Name { get; set; }

        public Dog(string name)
        {
            Name = name;
            secretName = "His Great Terribleness Mr. Bites-a-Lot";
        }

        public void RevealNames()
        {
            Console.WriteLine(leadin);
            Console.WriteLine(string.Format("{0} is really {1}", Name, secretName));
            string leadin = "Did you know?";
        }

        private string secretName;
    }