14 Replies - 3765 Views - Last Post: 29 February 2012 - 12:11 PM Rate Topic: -----

#1 ShadowyCore  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 07-April 09

Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 03:39 PM

Is it possible to get the type of an inherited class in the following manner?


abstract class MyClass
{
   MyClass Load(string filename)
   {
       ...
   }
}

class MyInheritor : MyClass
{
   MyInheritor Load(string filename)
   {
      ...
   }
}

class MyInheritor2 : MyClass
{
   ...
}




The goal is to enforce the MyClass return type in the Load(string) function to return a type the same as the inheritor, as in MyInheritor's implementation of Load(string).

I guess my question is is it possible, in a parent class, to force a child class to use its own type as a return type, so as to avoid allowing MyInheritor.Load(string) to return a type MyInheritor2?

I'd like to avoid generics, as it does not enforce using the specific child class, unless there is some other way of using <T> that I'm not aware of.

Thank you!

Is This A Good Question/Topic? 0
  • +

Replies To: Getting Type Of Abstract Class Inheritor?

#2 Sergio Tapia  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1252
  • View blog
  • Posts: 4,168
  • Joined: 27-January 10

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 04:04 PM

I'm going to wait for Baavgai to come in here and make my head explode.
Was This Post Helpful? 0
  • +
  • -

#3 ShadowyCore  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 07-April 09

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 04:14 PM

Who's Baavgai?
Was This Post Helpful? 1
  • +
  • -

#4 Sergio Tapia  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1252
  • View blog
  • Posts: 4,168
  • Joined: 27-January 10

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 04:33 PM

You will see. :lol:

(No but really, he's a great guy who is very knowledgeable and will shed much more light than I can - I'm here to learn as well!)
Was This Post Helpful? 0
  • +
  • -

#5 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 945
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 04:38 PM

It is easy enough. You can use the is keyword to tell what class the object is, even using polymorphism. You can then work with that something like this.

if (myObject is MyInheritor)
{
    MyInheritor newObjet = myObject as MyInheritor;
}


Was This Post Helpful? 0
  • +
  • -

#6 macosxnerd101  Icon User is offline

  • Self-Trained Economist
  • member icon




Reputation: 10396
  • View blog
  • Posts: 38,464
  • Joined: 27-December 08

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 04:43 PM

Check out type constraints on Generic parameters. You could use this to force T to be an instanceof (or subclass instanceof) the base class using the where T : <base class name> constraint.
Was This Post Helpful? 0
  • +
  • -

#7 ShadowyCore  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 07-April 09

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 04:45 PM

Well my goal is to force the inheritor's method to return the inheritor's type, so I need a generics-esque solution. For example:


interface MyInt
{
   MyInt Load()
}




But I want the return type of the Load() method to be the same as the implementer type of the interface.
Was This Post Helpful? 0
  • +
  • -

#8 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 945
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 04:51 PM

You use is to determine what type an object is, even using polymorphism. You can then safely cast it as an object of its own type using the as keyword like I mentioned above.

if (myObject is MyInheritor)
{
    MyInheritor myNewObject = myObject as MyInheritor;

    MyInheritor newValue = myNewObject.Load();
}



Alternatively, you can also after finding out what type it is using the is keyword cast it to get the right value.

if (myObject is MyInheritor)
{
    MyInheritor newObject = ((MyInheritor) myObject.Load();
}



*edit*
The object will return the right type because it knows what type it is. You just need to check the type outside of the class.
Was This Post Helpful? 0
  • +
  • -

#9 ShadowyCore  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 07-April 09

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 05:00 PM

Oh, so there is no way to get the inheriting class's type inside the parent class?
Was This Post Helpful? 0
  • +
  • -

#10 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 945
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 05:27 PM

Inside of the base class? Sure, use the this keyword to tell what class it is in side of the class.

if (this is MyInheritor)
{
    MyInheritor myObject = (MyInheritor)this.Load();
    return myObject;
}



However, you will run into problems with protection levels. Your best bet would be to wrap all of the objects inside a namespace of their own and use internal as the protection modifier. This way the Load method will be available only inside your assembly.

    public abstract class MyClass
    {
        protected string filename;

        internal MyClass Load(string filename)
        {
            this.filename = filename;

            MyClass inheritor = null;

            if (this is MyInheritor)
                inheritor = ((MyInheritor) this).Load(filename);
            return inheritor;
        }

    }

    public class MyInheritor : MyClass
    {
        new internal MyInheritor Load(string filename)
        {
            // Return the object of this type
        }
    }



*EDIT*
Messed up the call to Load. Fixed it.

This post has been edited by SixOfEleven: 05 July 2010 - 05:32 PM

Was This Post Helpful? 0
  • +
  • -

#11 ShadowyCore  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 07-April 09

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 06:14 PM

So, theoretically, could you


MyClass Load(string filepath)
{
   MyClass ret;

   ...

   if (!(ret.GetType() == this.GetType()))
      throw new Exception();

   return ret;
}



Was This Post Helpful? 0
  • +
  • -

#12 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 945
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 06:29 PM

Yes, you could.

Try the following program. You will get:

Quote

Load in MyClass.
Load in MyInheritor.


// Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Polymorphism.Inherited;

namespace Polymorphism
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass myObject = new MyInheritor();
            myObject.Load("filaef");
            if (myObject.GetType() != typeof(MyInheritor))
                Console.WriteLine("Wrong object type");
        }
    }
}

// MyClass.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymorphism.Inherited
{
    public abstract class MyClass
    {
        internal MyClass Load(string filename)
        {
            Console.WriteLine("Load in MyClass.");

            MyClass returnValue = null;

            if (this is MyInheritor)
                returnValue = ((MyInheritor) this).Load(filename);
            if (returnValue.GetType() != this.GetType())
                throw new Exception();

            return returnValue;
        }

    }
}

// MyInheritor.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymorphism.Inherited
{
    public class MyInheritor : MyClass
    {
        new internal MyInheritor Load(string filename)
        {
            Console.WriteLine("Load in MyInheritor.");
            return new MyInheritor();
        }
    }
}


This post has been edited by SixOfEleven: 05 July 2010 - 06:31 PM

Was This Post Helpful? 0
  • +
  • -

#13 ShadowyCore  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 07-April 09

Re: Getting Type Of Abstract Class Inheritor?

Posted 05 July 2010 - 06:54 PM

Or, to ensure even greater "type safety":


public abstract class MyClass
{
   public MyClass Load(string filepath)
   {
      MyClass ret = _customLoad(filepath);
      
      if (ret.GetType() != this.GetType())
         throw new Exception("Type mismatch.");
      else
         return ret;
   }

   protected abstract MyClass _customLoad(string filepath)
   {
      ...
   }
}




Just a thought?

EDIT: Crud, forgot to make _customLoad(string) abstract.

This post has been edited by ShadowyCore: 05 July 2010 - 06:56 PM

Was This Post Helpful? 0
  • +
  • -

#14 TwistedStem  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 29-February 12

Re: Getting Type Of Abstract Class Inheritor?

Posted 29 February 2012 - 11:59 AM

Generics are the answer to your question! Since you would most likely be instantiating the inheriting class in the base you can put a constraint on the generic that will only allow classes that have a parameterless constructor, which then will allow you to new it up like below.

abstract class MyClass<T> where T: new()
{
   public static T Load(string filename)
   {
      //TODO: do your common (base) stuff here with filename.
      return new T();
   }
}

class MyInheritor : MyClass<MyInheritor>
{

}

class MyInheritor2 : MyClass<MyInheritor2>
{

}



I changed the Load to be static so you can load without first instantiating your class
var myInstance = MyInheritor.Load("someFile.txt");


If you are instantiating MyInheritor before calling Load than I can't see way you would want to return the object you already have.
Was This Post Helpful? 0
  • +
  • -

#15 lordofduct  Icon User is offline

  • I'm a cheeseburger
  • member icon


Reputation: 2531
  • View blog
  • Posts: 4,631
  • Joined: 24-September 10

Re: Getting Type Of Abstract Class Inheritor?

Posted 29 February 2012 - 12:11 PM

Possible to hack out a way to do this? Yes, has been demonstrated already (see above).


Should you do this? Probably not. Sounds like very bad design of a class. Can you give an example of why you would need this?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1