简体   繁体   中英

Returning child type in Parent class

      public abstract class Base
      {
         public Base ClassReturn()
        {
            return this;
        }
      }

Is there possibility to return child type that invoked ClassReturn method? I've done that in extension method:

public static T ClassReturn<T>(this T obj) where T : Base
        {
            return (T) obj.ClassReturn();
        }

But I want to embeed it in Base class instead of extension method. Is there possibility to do that with generics?

I will copy my comment which describes what I want to achieve:

I need something similiar to builder pattern and I have different classes that depending on previous operations do something else, now I want to have a similiar functionality in every of them and when I use it I lose object type. So my solution is either implement that functionality multiple times in every class or create extension method. But I always thought when it is possible to make extension method for class then I can embeed that in class, but as I see it is not possible.

Full example:

 public class Child1 : Base
        {
            public Child1 Operation1()
            {
                Console.WriteLine("operation1");
                return this;
            }
        }

        public class Child2 : Base
        {
            public Child2 Operation2()
            {
                Console.WriteLine("operation2");
                return this;
            }
        }



        static void Main(string[] args)
        {
            Child1 ch = new Child1();
            ch.Operation1().Operation1().ClassReturn().Operation1()
        }

I can't use Operation1 after ClassReturn if I don't use extension method.

Try this one:

public abstract class Base<T> where T: Base<T>
{
    public T ClassReturn
    {
        get { return (T)this; }
    }
}

public class Child1 : Base<Child1>
{
}

public class Child2 : Base<Child2>
{
}

From your question and your comments, what you are trying to achieve is not possible directly from the type system. By returning an instance of Base you are specifically saying that all you are interested is that you have something that derives from Base, but that the specific class doesn't matter. Statically, the compiler no longer has the information it needs to perform a cast.

If you are trying to get the original type back statically, then you have to supply the information to the compiler, and in this case you can't guarantee that you have the correct information. In the example below, the instance is created from derived type A but attempted to be cast to derived type B through the extension, the compiler will allow the code to compile, but you'll get an exception at runtime.

public class A : Base { }
public class B : Base { }

public static class BaseExtensions
{
    public static T GetAsT<T>(this Base base)  where T: Base
    {
       return (T)base;
    }
}


public static void Main() 
{
    Base obj = new A();
    B b = obj.BaseAsT<B>(); // This compiles but causes an exception
}

You should look up the Liscov Substitution Principle to get information on how to properly work with base and derived classes in the system as a whole, and then write up a question dealing specifically with the result you are trying to achieve.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM