Is it possible to let an overridden method from a base class to return the type of the derived class?
What I mean is:

namespace test //with some "pseudo" code
{
    class Base<T>
    {
        //fields ...
        //properties ...
        // ...
        public virtual Base<T> BaseMethod()
        {
            //return new Base<T>;
        }
        // ...
    }

    class DerivedfromBase : Base<int>
    {
        // ...
        public override Base<int> BaseMethod()
        {
            //other things here
            return // a Base<int> type;
            //Can it return DerivedfromBase type here?
        }
        // ...
    }

 //   Main
{
    DerivedfromBase AA = new DerivedfromBase();
    //will compile, but run will give invalid cast exeption
    DerivedfromBase BB = (DerivedfromBase)AA.BaseMetod(); 
}
//}

Tried different things myself, but as I'm a still a learner and could find nothing useful on the web, I'm a bit stuck.
Hope someone can help me out here and thanks in advance. :)

Recommended Answers

All 14 Replies

Hi

Ok I'm really not clear on what you are asking here.

So I took your code and got it to compile - a few typos etc but got something working. I then renamed things and played around with it to give it more context - I find things easier to understand that way otherwise it all gets a bit abstract and dificult to follow!

I don't know if how I have renamed things and played around with them conveys your intentions or not but it does at least give us a working code baseline from which to start further discussions.

Hope what I have done helps, if not fire away.

using System;

namespace DaniWeb.Inheritance
{
    class Program
    {
        static void Main(string[] args)
        {
            IntegerFactory integerFactory = new IntegerFactory();
            StringFactory stringFactory = new StringFactory();

            var anInteger = integerFactory.BaseMethod();

            var aString = stringFactory.BaseMethod();

            Console.WriteLine("anInteger is type {0} and T is {1}", anInteger.GetType(), anInteger.GenericType);
            Console.WriteLine("watsit is type {0} and T is {1}", aString.GetType(), aString.GenericType);

            Console.ReadKey();
        }
    }

    public class GenericFactory<T>
    {
        public virtual string Name { get { return "Base"; } }
        public virtual Type GenericType { get { return typeof(T); } }

        public virtual GenericFactory<T> BaseMethod()
        {
            return new GenericFactory<T>();
        }
    }

    public class IntegerFactory : GenericFactory<int>
    {
        public override string Name { get { return "IntegerFactory"; } }

        public override GenericFactory<int> BaseMethod()
        {
            return new IntegerFactory();
        }
    }

    public class StringFactory : GenericFactory<string>
    {
        public override string Name { get { return "StringFactory"; } }

        public override GenericFactory<string> BaseMethod()
        {
            return new StringFactory();
        }
    }
}
commented: Thanks for the "factory" code. +15

Are you looking to return an instance (return this;) or just the int (return T;) ?

Just realied I have a typo

Console.WriteLine("watsit is type {0} and T is {1}",

Shoule be

Console.WriteLine("aString is type {0} and T is {1}",

Thanks DaveAmour, this could be a great way to help me out. But what what I really want is as priteas was asking, some sort of return this;

Where in my code do you want the "return this" to go?

Is this what you want?

using System;
using System.Data.SqlClient;

namespace DaniWeb.Inheritance
{
    class Program
    {
        static void Main(string[] args)
        {
            IntegerFactory integerFactory = new IntegerFactory();
            StringFactory stringFactory = new StringFactory();
            SqlCommandFactory sqlCommandFactory = new SqlCommandFactory();

            var anInteger = integerFactory.BaseMethod();
            var aString = sqlCommandFactory.BaseMethod();
            var aCommand = sqlCommandFactory.BaseMethod();

            Console.WriteLine("anInteger is type {0} and T is {1}", anInteger.GetType(), anInteger.GenericType);
            Console.WriteLine("aString is type {0} and T is {1}", aString.GetType(), aString.GenericType);
            Console.WriteLine("aCommand is type {0} and T is {1}", aCommand.GetType(), aCommand.GenericType);

            Console.ReadKey();
        }
    }

    public class GenericFactory<T>
    {
        public virtual string Name { get { return "Base"; } }
        public virtual Type GenericType { get { return typeof(T); } }

        public virtual GenericFactory<T> BaseMethod()
        {
            return new GenericFactory<T>();
        }
    }

    public class IntegerFactory : GenericFactory<int>
    {
        public override string Name { get { return "IntegerFactory"; } }

        public override GenericFactory<int> BaseMethod()
        {
            return this;
        }
    }

    public class StringFactory : GenericFactory<string>
    {
        public override string Name { get { return "StringFactory"; } }

        public override GenericFactory<string> BaseMethod()
        {
            return this;
        }
    }

    public class SqlCommandFactory : GenericFactory<SqlCommand>
    {
        public override string Name { get { return "SqlCommandFactory"; } }

        public override GenericFactory<SqlCommand> BaseMethod()
        {
            return this;
        }
    }
}

Tried different things myself, but as I'm a still a learner and could find nothing useful on the web, I'm a bit stuck.

It may help your search to know that what you're looking for is called return type covariance. To simplify your search drastically, C# doesn't support it even in the latest version. ;)

There's likely a workaround though, if you specify exactly what you're trying to accomplish rather than simply paraphrasing it for the sake of simplicity.

Perhaps it is better understood if I tell what I really like to do. Thought that would complicate matters, that why I started with some sort of sketch.
I want to design a small square matrix class and from it derive some real matrix class, complex number matrix etc. and do my own thing instead of using some linear packages that probably exist out there, with a lot of overhead I don't need. In doing so I want to inprove my C# skills.
Now the method in question is a matrix transpose that creates a new matrix, puts in the transposed values from the original and should return it as a real matrix or whatever.

I will struggle with this as I remember vagueley from Maths classes what a Matrix is but my domain knowledge in this area is not good so over to you other guys!

Thanks guys for all the answers so far.

@decepticon
As far as I know covariance and contravariance exist in C# at least as of version 4.0.
Read about those concepts, but they remind me of the first lyric of the beautiful song "Misty"
Look at me, I'm as helpless as a kitten up a tree

Going to use the whole weekend, and if I can defy my procrastination habbits, to study this. I believe there is my solution.

As far as I know covariance and contravariance exist in C# at least as of version 4.0.

This is true, but not for return types from methods.

commented: Thanks for the hint! +0

I am reading a book right now, called "C# in depth" (3rd ed.), the author mentions contravarience, and covarience in places, but I am not finished yet, so I don't know if the author addresses this problem directly. The author's name is John Skeet, I think he actually has a stack overflow account. The book also has references to his online blogs, but all the links have changed by now. You just have to do some creative googleing to find the blogs. The MSDN site would also probably have information about this topic.

Guys thanks again for all the tips and help.
It made me realize, I made a design flaw.
A matrix object should transpose itself and not return a new object with a transposed version of itself. I changed my code accordingly and it works. It is still under construction and eventualy I will post a snip.

Ok nice one, glad to help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.