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. Generics Casting [modified]

Generics Casting [modified]

Scheduled Pinned Locked Moved C#
tutorial
7 Posts 3 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.
  • G Offline
    G Offline
    gnjunge
    wrote on last edited by
    #1

    Am I missing something, or the example below is really impossible. The class called FirstImplementation derives from GenericClass, and the generic parameter used, FirstClass derives from Base. So from the outside I should be able to cast FirstImplementation to GenericClass

    public class Base
    {
        public int X { get; set; }
    }
    
    public class FirstClass : Base
    {
        public int Y { get; set; }
    }
    
    public abstract class GenericClass<T> where T: Base
    {
        public T Item { get; set;}
    }
    
    public class FirstImplementation : GenericClass<FirstClass>
    {
        public GenericClass<Base> Cast()
        {
            return (GenericClass<Base> )this; // --> doesn't work
    
        }
    }
    

    modified on Thursday, January 15, 2009 6:18 AM

    S S 2 Replies Last reply
    0
    • G gnjunge

      Am I missing something, or the example below is really impossible. The class called FirstImplementation derives from GenericClass, and the generic parameter used, FirstClass derives from Base. So from the outside I should be able to cast FirstImplementation to GenericClass

      public class Base
      {
          public int X { get; set; }
      }
      
      public class FirstClass : Base
      {
          public int Y { get; set; }
      }
      
      public abstract class GenericClass<T> where T: Base
      {
          public T Item { get; set;}
      }
      
      public class FirstImplementation : GenericClass<FirstClass>
      {
          public GenericClass<Base> Cast()
          {
              return (GenericClass<Base> )this; // --> doesn't work
      
          }
      }
      

      modified on Thursday, January 15, 2009 6:18 AM

      S Offline
      S Offline
      Simon P Stevens
      wrote on last edited by
      #2

      That's not how generics work unfortunately. You can't do this

              GenericClass<firstclass> var1;
              GenericClass<base> var2;
      
              var2 = (GenericClass<base> )var1;
      

      Your var1 & var2 variables are different types. One is a generic class using base as it's type member, and one is using FirstClass as it's type member, you can't cast one to the other, just because FirstClass is a subclass of Base. var1 isn't a subclass of var2. What generics effectively do is define a new class using the type you specified. So it effectively equates to this:

      public class GenericClassUsingBase
      {
          public Base Item
          {
              get;
              set;
          }
      }
      
      public class GenericClassUsingFirstClass
      {
          public FirstClass Item
          {
              get;
              set;
          }
      }
      

      You'll see if you try and cast these you can't do that either:

              GenericClassUsingFirstClass var1;
              GenericClassUsingBase var2;
      
              var2 = (GenericClassUsingBase)var1;
      

      They are basically different types, just because they are using type parameters that subclass each other doesn't make them subclasses of themselves.

      Simon

      G 1 Reply Last reply
      0
      • S Simon P Stevens

        That's not how generics work unfortunately. You can't do this

                GenericClass<firstclass> var1;
                GenericClass<base> var2;
        
                var2 = (GenericClass<base> )var1;
        

        Your var1 & var2 variables are different types. One is a generic class using base as it's type member, and one is using FirstClass as it's type member, you can't cast one to the other, just because FirstClass is a subclass of Base. var1 isn't a subclass of var2. What generics effectively do is define a new class using the type you specified. So it effectively equates to this:

        public class GenericClassUsingBase
        {
            public Base Item
            {
                get;
                set;
            }
        }
        
        public class GenericClassUsingFirstClass
        {
            public FirstClass Item
            {
                get;
                set;
            }
        }
        

        You'll see if you try and cast these you can't do that either:

                GenericClassUsingFirstClass var1;
                GenericClassUsingBase var2;
        
                var2 = (GenericClassUsingBase)var1;
        

        They are basically different types, just because they are using type parameters that subclass each other doesn't make them subclasses of themselves.

        Simon

        G Offline
        G Offline
        gnjunge
        wrote on last edited by
        #3

        Thanks. Great explanation. I guess I'm not the only one who bumps into this. Any known workarounds? Or rethink the whole implementation from scratch?

        S 1 Reply Last reply
        0
        • G gnjunge

          Thanks. Great explanation. I guess I'm not the only one who bumps into this. Any known workarounds? Or rethink the whole implementation from scratch?

          S Offline
          S Offline
          Simon P Stevens
          wrote on last edited by
          #4

          gnjunge wrote:

          Any known workarounds?

          That kind of depends what you are trying to do. If you are trying to treat generics of a class tree as a tree themselves, I suspect you are slightly misusing the idea of generic classes. You might be better defining explicit classes instead of generic ones, and then having them all inherit from the same interface or abstract class instead if you need that. What is it you are trying to archive?

          Simon

          G 1 Reply Last reply
          0
          • G gnjunge

            Am I missing something, or the example below is really impossible. The class called FirstImplementation derives from GenericClass, and the generic parameter used, FirstClass derives from Base. So from the outside I should be able to cast FirstImplementation to GenericClass

            public class Base
            {
                public int X { get; set; }
            }
            
            public class FirstClass : Base
            {
                public int Y { get; set; }
            }
            
            public abstract class GenericClass<T> where T: Base
            {
                public T Item { get; set;}
            }
            
            public class FirstImplementation : GenericClass<FirstClass>
            {
                public GenericClass<Base> Cast()
                {
                    return (GenericClass<Base> )this; // --> doesn't work
            
                }
            }
            

            modified on Thursday, January 15, 2009 6:18 AM

            S Offline
            S Offline
            S Senthil Kumar
            wrote on last edited by
            #5

            C# 4.0 brings generic covariance[^]. While the current code will still not compile, inserting an interface will get you going.

            public interface IGenericClass where T : Base { public T Item {get; } } // note, having a set will not work

            public abstract class GenericClass : IGenericClass {...}

            var derived = new FirstImplementation();
            IGenericClass<Base> baseInterface = derived;

            C# 4.0 is still in CTP stage though.

            Regards Senthil [MVP - Visual C#] _____________________________ My Home Page |My Blog | My Articles | My Flickr | WinMacro

            G 1 Reply Last reply
            0
            • S Simon P Stevens

              gnjunge wrote:

              Any known workarounds?

              That kind of depends what you are trying to do. If you are trying to treat generics of a class tree as a tree themselves, I suspect you are slightly misusing the idea of generic classes. You might be better defining explicit classes instead of generic ones, and then having them all inherit from the same interface or abstract class instead if you need that. What is it you are trying to archive?

              Simon

              G Offline
              G Offline
              gnjunge
              wrote on last edited by
              #6

              For now I made my own work around. The code has changed multiple times, and I'm sure there was a reason for using generics. Have to check it when I have time.

              1 Reply Last reply
              0
              • S S Senthil Kumar

                C# 4.0 brings generic covariance[^]. While the current code will still not compile, inserting an interface will get you going.

                public interface IGenericClass where T : Base { public T Item {get; } } // note, having a set will not work

                public abstract class GenericClass : IGenericClass {...}

                var derived = new FirstImplementation();
                IGenericClass<Base> baseInterface = derived;

                C# 4.0 is still in CTP stage though.

                Regards Senthil [MVP - Visual C#] _____________________________ My Home Page |My Blog | My Articles | My Flickr | WinMacro

                G Offline
                G Offline
                gnjunge
                wrote on last edited by
                #7

                That's great.

                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