Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. abstarct class basic question [modified]

abstarct class basic question [modified]

Scheduled Pinned Locked Moved C#
csharplinqtutorialquestionlounge
25 Posts 8 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R RobCroll
    abstract class b
    {
        public dynamic Create()
        {
            return Activator.CreateInstance(this.GetType());
        }
    }
    

    "You get that on the big jobs."

    P Offline
    P Offline
    PozzaVecia
    wrote on last edited by
    #3

    Thanks a lot It works . The only constrain is that you need VS10 to use "dymanic". Is there an old workaround?

    B L 2 Replies Last reply
    0
    • P PozzaVecia

      Thanks a lot It works . The only constrain is that you need VS10 to use "dymanic". Is there an old workaround?

      B Offline
      B Offline
      BobJanova
      wrote on last edited by
      #4

      I don't think you need dynamic here. You know what type the object will be: it will be a b.

      public virtual b Create() { return (b)Activator.CreateInstance(GetType()); }

      It's probably best to make this method virtual so that subclasses can do something different if they need to. This is quite an unusual thing to want to do unless you are trying to copy an object:

      void SomeFunction(b instance){
      b copy = instance.Create();
      instance.CopyTo(copy);
      }

      ... as it requires you to have an instance of the object to create the new one from.

      P 1 Reply Last reply
      0
      • B BobJanova

        I don't think you need dynamic here. You know what type the object will be: it will be a b.

        public virtual b Create() { return (b)Activator.CreateInstance(GetType()); }

        It's probably best to make this method virtual so that subclasses can do something different if they need to. This is quite an unusual thing to want to do unless you are trying to copy an object:

        void SomeFunction(b instance){
        b copy = instance.Create();
        instance.CopyTo(copy);
        }

        ... as it requires you to have an instance of the object to create the new one from.

        P Offline
        P Offline
        PozzaVecia
        wrote on last edited by
        #5

        Thanks a lot! So suppose I do the following,

        abstract class b
        {
        public virtual b Create() { return (b)Activator.CreateInstance(GetType()); }
        }

        I'm not able to use method of the derived class?

        class Program
        {
        static void Main(string[] args)
        {
        D1 myClass = new D1();
        D1 newClass = myClass.Create();
        Console.WriteLine(newClass.KM);

                // Bur
                b myClassAb = new D1();
                b newClassAb = myClassAb.Create();
                Console.WriteLine(newClassAb.KM);//KM is not avaiable :(
            }
        }
        
        B 1 Reply Last reply
        0
        • P PozzaVecia

          Thanks a lot! So suppose I do the following,

          abstract class b
          {
          public virtual b Create() { return (b)Activator.CreateInstance(GetType()); }
          }

          I'm not able to use method of the derived class?

          class Program
          {
          static void Main(string[] args)
          {
          D1 myClass = new D1();
          D1 newClass = myClass.Create();
          Console.WriteLine(newClass.KM);

                  // Bur
                  b myClassAb = new D1();
                  b newClassAb = myClassAb.Create();
                  Console.WriteLine(newClassAb.KM);//KM is not avaiable :(
              }
          }
          
          B Offline
          B Offline
          BobJanova
          wrote on last edited by
          #6

          That's correct (unless you cast it). That's kind of an unavoidable consequence of putting any method on the base class. Typically in an abstract class hierarchy, the base class will define (either concrete or abstract) most of the public interface, so you can do most things through the base. If you know that you are working with D1, after all, you can just create a new instance with new D1(). The dynamic Create method is only needed when you want a new instance of the same type as another object, and you don't know what type that is, so you wouldn't be able to call class-specific functionality on it anyway.

          P 1 Reply Last reply
          0
          • B BobJanova

            That's correct (unless you cast it). That's kind of an unavoidable consequence of putting any method on the base class. Typically in an abstract class hierarchy, the base class will define (either concrete or abstract) most of the public interface, so you can do most things through the base. If you know that you are working with D1, after all, you can just create a new instance with new D1(). The dynamic Create method is only needed when you want a new instance of the same type as another object, and you don't know what type that is, so you wouldn't be able to call class-specific functionality on it anyway.

            P Offline
            P Offline
            PozzaVecia
            wrote on last edited by
            #7

            Thank you for your clear answer. So:

            b myClassAb = new D1();
            b newClassAb = myClassAb.Create();

            even if newClassAb is a D1 type, I cannot use D1 methods unless cast it. So no way to avoid to write the same piece of code in each derived class even if they basically do the same thing, if I want to use all methods of derived class. Is it?

            class D1:b
            {
            ..
            public D1 Create() { return new D1(); }
            }
            class D2 : b
            {
            ..
            public D2 Create() { return new D2(); }
            }

            M B 2 Replies Last reply
            0
            • P PozzaVecia

              Thank you for your clear answer. So:

              b myClassAb = new D1();
              b newClassAb = myClassAb.Create();

              even if newClassAb is a D1 type, I cannot use D1 methods unless cast it. So no way to avoid to write the same piece of code in each derived class even if they basically do the same thing, if I want to use all methods of derived class. Is it?

              class D1:b
              {
              ..
              public D1 Create() { return new D1(); }
              }
              class D2 : b
              {
              ..
              public D2 Create() { return new D2(); }
              }

              M Offline
              M Offline
              Mirko1980
              wrote on last edited by
              #8

              You can use generics like this:

              abstract class b<T> where T: b, new()
              {
              ...
              public T Create() { return new T(); }
              }

              class D1 : b<D1>
              {
              ...
              }
              class D2 : b<D2>
              {
              ...
              }

              So, you can do:

              D1 myClassD1 = new D1();
              D1 newClassD1 = D1.Create();

              But, you can't do anymore:

              b myClassAb = new D1;
              D1 newClassAb = myClassAb.Create();

              because you'd have to specify the generic type for class b.

              B 1 Reply Last reply
              0
              • P PozzaVecia

                Hi is in the following example is possible to add method Create() directly in the abstract class instead of in each derived class (basically the methos do the same: return inizialide class of its type). Something like this, that it doesn't works: abstract class b { public b Create() { { return new b(); } // but can not understand the derived class type } } Hope to be clear Thanks for your time

                using System;
                using System.Collections.Generic;
                using System.Linq;
                using System.Text;

                namespace general
                {

                class Program
                {
                    static void Main(string\[\] args)
                    {
                        D1 myClass = new D1();
                        D1 newClass = myClass.Create();
                        
                        //this is what I would like
                        //b myClassAb = new D1();
                        //b newClassAb = myClassAb.Create();
                    }
                }
                
                abstract class b
                {
                   //do no work in this way !!!
                   //public b Create() { return new b(); } // but can not understand the derived class type
                
                }
                
                class D1:b 
                {
                    public double KM ;
                    public D1() { KM = 1.0; }
                    public D1 Create() { return new D1(); }
                }
                class D2 : b 
                {
                    public double KM ;
                    public D2() { KM = 2.0; }
                    public D2 Create() { return new D2(); }
                }
                

                }

                modified on Wednesday, June 1, 2011 3:15 AM

                S Offline
                S Offline
                Steven Pinto2000
                wrote on last edited by
                #9

                using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace general { class Program { static void Main(string[] args) { D1 myClass = new D1(); D1 newClass = myClass.Create(); //this is what I would like b myClassAb = new D1(); b newClassAb = myClassAb.Create<D1>(); newClass.KM = 1.23; } } abstract class b { //work in this way !!! public T Create<T>() where T:new() { return new T(); } } class D1 : b { public double KM; public D1() { KM = 1.0; } // public D1 Create() { return new D1(); } } class D2 : b { public double KM; public D2() { KM = 2.0; } // public D2 Create() { return new D2(); } } } here is one solution using generics

                modified on Wednesday, June 1, 2011 9:53 AM

                P 1 Reply Last reply
                0
                • P PozzaVecia

                  Thanks a lot It works . The only constrain is that you need VS10 to use "dymanic". Is there an old workaround?

                  L Offline
                  L Offline
                  Luc Pattyn
                  wrote on last edited by
                  #10

                  Actually, you don't need Visual Studio at all. What you are meaning to say is "this requires .NET 4.0" :)

                  Luc Pattyn [My Articles] Nil Volentibus Arduum

                  The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
                  Please use <PRE> tags for code snippets, they improve readability.
                  CP Vanity has been updated to V2.3

                  P 1 Reply Last reply
                  0
                  • S Steven Pinto2000

                    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace general { class Program { static void Main(string[] args) { D1 myClass = new D1(); D1 newClass = myClass.Create(); //this is what I would like b myClassAb = new D1(); b newClassAb = myClassAb.Create<D1>(); newClass.KM = 1.23; } } abstract class b { //work in this way !!! public T Create<T>() where T:new() { return new T(); } } class D1 : b { public double KM; public D1() { KM = 1.0; } // public D1 Create() { return new D1(); } } class D2 : b { public double KM; public D2() { KM = 2.0; } // public D2 Create() { return new D2(); } } } here is one solution using generics

                    modified on Wednesday, June 1, 2011 9:53 AM

                    P Offline
                    P Offline
                    PozzaVecia
                    wrote on last edited by
                    #11

                    Sorry probably I did not explain very well the problem. I need to have avaiable methods in newClassAb //this is what I would like b myClassAb = new D1(); b newClassAb = myClassAb.Create<D1>(); //This is what I need to see K from newClassAb Console.WriteLine(newClassAb.K)>//but I can't see .K avaiable Thanks for your time

                    modified on Wednesday, June 1, 2011 7:32 AM

                    S 1 Reply Last reply
                    0
                    • P PozzaVecia

                      Thank you for your clear answer. So:

                      b myClassAb = new D1();
                      b newClassAb = myClassAb.Create();

                      even if newClassAb is a D1 type, I cannot use D1 methods unless cast it. So no way to avoid to write the same piece of code in each derived class even if they basically do the same thing, if I want to use all methods of derived class. Is it?

                      class D1:b
                      {
                      ..
                      public D1 Create() { return new D1(); }
                      }
                      class D2 : b
                      {
                      ..
                      public D2 Create() { return new D2(); }
                      }

                      B Offline
                      B Offline
                      BobJanova
                      wrote on last edited by
                      #12

                      There's a very simple way, if you know you want a D1: call new D1() not myD1Instance.Create(). I'm guessing this is a simplified example, because it simply doesn't make sense to do things this way in most cases. What is your actual problem? Accepting for the moment that you need a Create method at all: If you know that an instance of b is actually a D1 (for example within the D1 class itself) then you can cast the result of Create safely. Casting is not necessarily bad (it's safer than the use of dynamic, I would say). For example, in some similar code to what I have at the moment for cloning objects in an inheritance tree:

                      class b {
                      private int someField;

                      public b Copy() {
                      b newB = Create();
                      CopyTo(newB);
                      return newB;
                      }

                      protected virtual void CopyTo(b newB){
                      // copy properties into the target
                      newB.someField = someField;
                      }

                      class D1 : b {
                      private double derivedField;

                      protected override void CopyTo(b newD1){
                      // This method will only be called if we are a D1,
                      // and therefore the result of Create is also a D1,
                      // and therefore the parameter is also a D1
                      D1 target = (D1)newD1; // ... so this must succeed
                      target.derivedField = derivedField; // ... and we can access D1's members
                      }
                      }

                      Outside the class tree, it's unlikely that you know for sure at compile time which of the classes you have an instance of (otherwise you wouldn't need the abstract base class at all), so you can normally only cast the result inside the class, or using if(my is D1) type tests. And if you find yourself writing those you probably just found somewhere that an abstract method should be provided on the base class.

                      1 Reply Last reply
                      0
                      • M Mirko1980

                        You can use generics like this:

                        abstract class b<T> where T: b, new()
                        {
                        ...
                        public T Create() { return new T(); }
                        }

                        class D1 : b<D1>
                        {
                        ...
                        }
                        class D2 : b<D2>
                        {
                        ...
                        }

                        So, you can do:

                        D1 myClassD1 = new D1();
                        D1 newClassD1 = D1.Create();

                        But, you can't do anymore:

                        b myClassAb = new D1;
                        D1 newClassAb = myClassAb.Create();

                        because you'd have to specify the generic type for class b.

                        B Offline
                        B Offline
                        BobJanova
                        wrote on last edited by
                        #13

                        Now you can't call Create on an arbitrary b instance, which renders it pointless.

                        M 1 Reply Last reply
                        0
                        • P PozzaVecia

                          Hi is in the following example is possible to add method Create() directly in the abstract class instead of in each derived class (basically the methos do the same: return inizialide class of its type). Something like this, that it doesn't works: abstract class b { public b Create() { { return new b(); } // but can not understand the derived class type } } Hope to be clear Thanks for your time

                          using System;
                          using System.Collections.Generic;
                          using System.Linq;
                          using System.Text;

                          namespace general
                          {

                          class Program
                          {
                              static void Main(string\[\] args)
                              {
                                  D1 myClass = new D1();
                                  D1 newClass = myClass.Create();
                                  
                                  //this is what I would like
                                  //b myClassAb = new D1();
                                  //b newClassAb = myClassAb.Create();
                              }
                          }
                          
                          abstract class b
                          {
                             //do no work in this way !!!
                             //public b Create() { return new b(); } // but can not understand the derived class type
                          
                          }
                          
                          class D1:b 
                          {
                              public double KM ;
                              public D1() { KM = 1.0; }
                              public D1 Create() { return new D1(); }
                          }
                          class D2 : b 
                          {
                              public double KM ;
                              public D2() { KM = 2.0; }
                              public D2 Create() { return new D2(); }
                          }
                          

                          }

                          modified on Wednesday, June 1, 2011 3:15 AM

                          B Offline
                          B Offline
                          BobJanova
                          wrote on last edited by
                          #14

                          In response to your modification: KM should clearly be defined on the base class. It should probably also be a property.

                          abstract class b
                          {
                              public double KM { get; protected set; }  // C# 2.0 automatic property syntax
                              public b Create() { return Activator.CreateInstance(GetType()); }
                          }
                          
                          class D1:b 
                          {
                              public D1() { KM = 1.0; }
                          }
                          class D2 : b 
                          {
                              public D2() { KM = 2.0; }
                          }
                          
                          P 1 Reply Last reply
                          0
                          • B BobJanova

                            In response to your modification: KM should clearly be defined on the base class. It should probably also be a property.

                            abstract class b
                            {
                                public double KM { get; protected set; }  // C# 2.0 automatic property syntax
                                public b Create() { return Activator.CreateInstance(GetType()); }
                            }
                            
                            class D1:b 
                            {
                                public D1() { KM = 1.0; }
                            }
                            class D2 : b 
                            {
                                public D2() { KM = 2.0; }
                            }
                            
                            P Offline
                            P Offline
                            PozzaVecia
                            wrote on last edited by
                            #15

                            Console.WriteLine(b.//<big>b.KM is still not avaiable!!</big>}

                            namespace general
                            {

                            class Program
                            {
                            static void Main(string[] args)
                            {

                            //this is what I would like
                            b myClassAb = new D1();
                            b newClassAb = myClassAb.Create();
                            Console.WriteLine(b.//K is still not avaiable!!}
                            }

                            abstract class b
                            {
                            public double KM { get; protected set; } // C# 2.0 automatic property syntax
                            public b Create() { return (b)Activator.CreateInstance(GetType()); }
                            }

                            class D1 : b
                            {
                            public D1() { KM = 1.0; }
                            }
                            class D2 : b
                            {
                            public D2() { KM = 2.0; }
                            }

                            B 1 Reply Last reply
                            0
                            • P PozzaVecia

                              Console.WriteLine(b.//<big>b.KM is still not avaiable!!</big>}

                              namespace general
                              {

                              class Program
                              {
                              static void Main(string[] args)
                              {

                              //this is what I would like
                              b myClassAb = new D1();
                              b newClassAb = myClassAb.Create();
                              Console.WriteLine(b.//K is still not avaiable!!}
                              }

                              abstract class b
                              {
                              public double KM { get; protected set; } // C# 2.0 automatic property syntax
                              public b Create() { return (b)Activator.CreateInstance(GetType()); }
                              }

                              class D1 : b
                              {
                              public D1() { KM = 1.0; }
                              }
                              class D2 : b
                              {
                              public D2() { KM = 2.0; }
                              }

                              B Offline
                              B Offline
                              BobJanova
                              wrote on last edited by
                              #16

                              You should be able to use newClassAb.KM.

                              P 1 Reply Last reply
                              0
                              • B BobJanova

                                You should be able to use newClassAb.KM.

                                P Offline
                                P Offline
                                PozzaVecia
                                wrote on last edited by
                                #17

                                Great!!!! It works...Thanks a lot:cool:

                                1 Reply Last reply
                                0
                                • L Luc Pattyn

                                  Actually, you don't need Visual Studio at all. What you are meaning to say is "this requires .NET 4.0" :)

                                  Luc Pattyn [My Articles] Nil Volentibus Arduum

                                  The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
                                  Please use <PRE> tags for code snippets, they improve readability.
                                  CP Vanity has been updated to V2.3

                                  P Offline
                                  P Offline
                                  PIEBALDconsult
                                  wrote on last edited by
                                  #18

                                  :thumbsup:

                                  1 Reply Last reply
                                  0
                                  • B BobJanova

                                    Now you can't call Create on an arbitrary b instance, which renders it pointless.

                                    M Offline
                                    M Offline
                                    Mirko1980
                                    wrote on last edited by
                                    #19

                                    I said that at the end of my post. I agree you are losing many advatages of polymorphism, but, at least, you can reuse the Create login in multple classes.

                                    1 Reply Last reply
                                    0
                                    • P PozzaVecia

                                      Sorry probably I did not explain very well the problem. I need to have avaiable methods in newClassAb //this is what I would like b myClassAb = new D1(); b newClassAb = myClassAb.Create<D1>(); //This is what I need to see K from newClassAb Console.WriteLine(newClassAb.K)>//but I can't see .K avaiable Thanks for your time

                                      modified on Wednesday, June 1, 2011 7:32 AM

                                      S Offline
                                      S Offline
                                      Steven Pinto2000
                                      wrote on last edited by
                                      #20

                                      what is K is it KM well i can see KM try it once more because there was some error in my code

                                      P 1 Reply Last reply
                                      0
                                      • S Steven Pinto2000

                                        what is K is it KM well i can see KM try it once more because there was some error in my code

                                        P Offline
                                        P Offline
                                        PozzaVecia
                                        wrote on last edited by
                                        #21

                                        b myClassAb = new D1();
                                        b newClassAb = myClassAb.Create<D1>();
                                        newClassAb.KM = 1.23;

                                        apparently return this error" Error 1 'general.b' does not contain a definition for 'KM' and no extension method 'KM' accepting a first argument of type 'general.b' could be found (are you missing a using directive or an assembly reference?)" The working solution example, thanks to BobJanova is:

                                        using System;
                                        using System.Collections.Generic;
                                        using System.Linq;
                                        using System.Text;

                                        namespace general
                                        {

                                        class Program
                                        {
                                        static void Main(string[] args)
                                        {

                                        //this is what I would like
                                        b myClassAb = new D1();
                                        b newClassAb = myClassAb.Create();
                                        Console.WriteLine(newClassAb.KM);
                                        }
                                        }

                                        abstract class b
                                        {
                                        public double KM { get; protected set; } // C# 2.0 automatic property syntax
                                        public b Create() { return (b)Activator.CreateInstance(GetType()); }
                                        }

                                        class D1 : b
                                        {
                                        public D1() { KM = 1.0; }
                                        }
                                        class D2 : b
                                        {
                                        public D2() { KM = 2.0; }
                                        }
                                        }

                                        1 Reply Last reply
                                        0
                                        • P PozzaVecia

                                          Hi is in the following example is possible to add method Create() directly in the abstract class instead of in each derived class (basically the methos do the same: return inizialide class of its type). Something like this, that it doesn't works: abstract class b { public b Create() { { return new b(); } // but can not understand the derived class type } } Hope to be clear Thanks for your time

                                          using System;
                                          using System.Collections.Generic;
                                          using System.Linq;
                                          using System.Text;

                                          namespace general
                                          {

                                          class Program
                                          {
                                              static void Main(string\[\] args)
                                              {
                                                  D1 myClass = new D1();
                                                  D1 newClass = myClass.Create();
                                                  
                                                  //this is what I would like
                                                  //b myClassAb = new D1();
                                                  //b newClassAb = myClassAb.Create();
                                              }
                                          }
                                          
                                          abstract class b
                                          {
                                             //do no work in this way !!!
                                             //public b Create() { return new b(); } // but can not understand the derived class type
                                          
                                          }
                                          
                                          class D1:b 
                                          {
                                              public double KM ;
                                              public D1() { KM = 1.0; }
                                              public D1 Create() { return new D1(); }
                                          }
                                          class D2 : b 
                                          {
                                              public double KM ;
                                              public D2() { KM = 2.0; }
                                              public D2 Create() { return new D2(); }
                                          }
                                          

                                          }

                                          modified on Wednesday, June 1, 2011 3:15 AM

                                          _ Offline
                                          _ Offline
                                          _Erik_
                                          wrote on last edited by
                                          #22

                                          I am sorry but, what is the point in creating an instance of a class to just create another instance of the same class? I mean, since Create method is not static it would just work as a constructor so, why don't you just use a constructor? For example, what you want to do is this:

                                          D1 obj = new D1();
                                          D1 obj2 = D1.Create();

                                          And what I am saying is... why not?

                                          D1 obj = new D1();
                                          D1 obj2 = new D1();

                                          I guess you want a static Create method in your base class, don't you? In this case you will have to make your Create method static and use generics:

                                          abstract class BaseClass
                                          {
                                          public static T Create<T>() where T : BaseClass, new()
                                          {
                                          return new T();
                                          }
                                          }

                                          class DerivedClass : BaseClass { }

                                          This way you could use it like this:

                                          DerivedClass obj = BaseClass.Create<DerivedClass>();

                                          P 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups