Rafael Herscovici
Rafael Herscovici

Reputation: 17094

How to get type of a derived class from another derived class

I have the (pseudo) code:

public class GlobalClass
{
    public GlobalClass()
    {
        var x = this.GetType().Name // Returns "Channels"
        // WHAT TO DO HERE?
    }
}

public class BaseClass
{
    public string Title { get; set; }
}

And using this code:

public class Channels : GlobalClass
{
    public Channels()
    {

    }

    public class Channel : BaseClass
    {

    }
}

Where the comment is (// WHAT TO DO HERE?), I want to get the runtime type of BaseClass, where in my sample code should return Channel.

I am open to different approaches, but only if it's accompanied with an explanation why I should change the code.

Upvotes: 1

Views: 813

Answers (4)

Alexis Pautrot
Alexis Pautrot

Reputation: 1165

You can use reflection like this:

using System.Reflection;

...

public class GlobalClass
{
    public GlobalClass()
    {
        Type[] types = Assembly.GetExecutingAssembly ().GetTypes ();
        foreach ( Type t in types )
        {
            if ( t.BaseType == typeof ( BaseClass ) )
            {
                Console.WriteLine ( "I found a class " + t.Name + " that subclass BaseClass" );
            }
        }
    }
}

See also Stack Overflow question List of classes in an assembly.

Upvotes: 0

Nuffin
Nuffin

Reputation: 3972

To get the runtime type of anything, you first need an object instance to get the type from. So with your given structure, that's not possible.

There are two possible approaches:

  1. Add a BaseClass parameter to the constructor of your GlobalClass:

    public class GlobalClass
    {
        public GlobalClass(BaseClass data)
        {
            var dataType = data == null ? null : data.GetType();
            // do something with the type
        }
    }
    
    public class Channels : GlobalClass
    {
        public Channels(Channel data) : base(data)
        {
    
        }
    
        public class Channel : BaseClass
        {
    
        }
    }
    
  2. Pass the type to the constructor directly:

    public class GlobalClass
    {
        public GlobalClass(Type actualType)
        {
            Debug.Assert(typeof(BaseClass).IsAssignableFrom(actualType));
        }
    }
    
    public class Channels : GlobalClass
    {
        public Channels() : base(typeof(Channel))
        {
    
        }
    
        public class Channel : BaseClass
        {
    
        }
    }
    

If the structure for some reason doesn't allow generics here (as Danny Chen suggested), I'd personally prefer the second approach, since that doesn't need an actual instance.

Upvotes: 0

Cheng Chen
Cheng Chen

Reputation: 43503

I think you need a generic class here, something like:

    public class GlobalClass<T> where T : BaseClass
    {
        public GlobalClass()
        {
            var theType = typeof(T);    //you got it
        }
    }
    public class BaseClass
    {
        public string Title { get; set; }
    }

    public class Channel : BaseClass { }
    public class Channels : GlobalClass<Channel> { }

Upvotes: 2

Azodious
Azodious

Reputation: 13872

is operator is just for that purpose.

getType() method with class Type can also be used.

class Example 
{
    static void ShowTypeInfo (object o) 
    {  
        Console.WriteLine ("type name = {0}, 
                            full type name = {1}", o.GetType(), 
                            o.GetType().FullName ); 
    }

    public static void Main()
    { 
        long longType = 99; 
        Example example= new Example(); 

        ShowTypeInfo (example); 
        ShowTypeInfo (longType); 
    }
}

Upvotes: 0

Related Questions