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. Cast Action<T> to Action<object> [modified]

Cast Action<T> to Action<object> [modified]

Scheduled Pinned Locked Moved C#
helptutorial
29 Posts 10 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.
  • A Adriaan Davel

    After much painfull and brain numbing reading I still don't understand why its not possible to cast between Action<T> and Action<object>, can anyone please explain this in small words (I currently have the brain of a 5 year old). There was a poem written along time ago by a person dying with lots of pain, he called it 'Brother Pain', I'm about to write a poem called 'Brother Cannot implicitly convert type 'System.Action<T>' to 'System.Action<object>'' An example:

    public class Base
    {
    public Func<object> OnComplete {get;set;}
    public Base(Func<object> onComplete)
    {
    OnComplete = onComplete;
    }
    }
    public class GenericBase<T> : Base
    {
    public GenericBase(Func<T> onComplete) : base(onComplete) //Error
    {
    OnComplete = onComplete; //Error
    }
    }

    ____________________________________________________________ Be brave little warrior, be VERY brave

    modified on Thursday, March 31, 2011 3:22 AM

    J Offline
    J Offline
    J4amieC
    wrote on last edited by
    #15

    Why not just to the following, from what I could see would give youthe exact same result, with the benefit of actually compiling!

    public interface IBase
    {
    Func OnComplete { get; set; }
    }

    public class Base : IBase
    {

    public Base(Func onComplete)
    {
        OnComplete = onComplete;
    }
    
    public Func OnComplete { get; set; }
    

    }
    public class GenericBase : IBase
    {
    public GenericBase(Func onComplete)
    {
    OnComplete = onComplete;
    }

    public Func OnComplete { get; set; }
    

    }

    1 Reply Last reply
    0
    • A Adriaan Davel

      After much painfull and brain numbing reading I still don't understand why its not possible to cast between Action<T> and Action<object>, can anyone please explain this in small words (I currently have the brain of a 5 year old). There was a poem written along time ago by a person dying with lots of pain, he called it 'Brother Pain', I'm about to write a poem called 'Brother Cannot implicitly convert type 'System.Action<T>' to 'System.Action<object>'' An example:

      public class Base
      {
      public Func<object> OnComplete {get;set;}
      public Base(Func<object> onComplete)
      {
      OnComplete = onComplete;
      }
      }
      public class GenericBase<T> : Base
      {
      public GenericBase(Func<T> onComplete) : base(onComplete) //Error
      {
      OnComplete = onComplete; //Error
      }
      }

      ____________________________________________________________ Be brave little warrior, be VERY brave

      modified on Thursday, March 31, 2011 3:22 AM

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

      Generic inheritance is a bit complicated. Here's the reason that you can't cast 'down' the generic type parameter inheritance tree. Imagine this test class:

      class BadMistake {
      void CompleteHandler(Dictionary<string,int> complexParameter){
      // some stuff
      }

      GenericBase<Dictionary<string,int>> instance;

      public void CauseDeath(){
      instance = new GenericBase<Dictionary<string,int>>(CompleteHandler);
      ((Base)instance).OnComplete(16);
      }
      }

      Now, CompleteHandler is expecting to be passed a Dictionary, and you can't compile something which would cause that not to be the case. But using the base class, you can pass an int (or anything else) to it. Method parameter compatibility for generics works backwards. This example will compile if the type parameter in the base is a subclass of T, for example try:

      public class Base
      {
      public Func<T> OnComplete {get;set;} where T:Panel
      public Base(Func<T> onComplete) where T:Panel
      {
      OnComplete = onComplete;
      }
      }
      public class GenericBase<T> : Base
      {
      public GenericBase(Func<T> onComplete) where T:UserControl : base(onComplete)
      {
      OnComplete = onComplete;
      }
      }

      (if I got the syntax on the constructor there right). Also, there isn't really a reason to make a non generic base type and inherit from it in this way. You can just use a GenericBase<object> if you want one that can deal with anything.

      1 Reply Last reply
      0
      • P Pete OHanlon

        That's exactly what I'm saying. The thing is though, generics were brought in for things like type safety and to prevent aid the developer move away from boxing/unboxing. By having object as the generic type, you've just gone back to having a boxing/unboxing issue - and you're no better off than just passing Action across rather than the generic Action.

        I'm not a stalker, I just know things. Oh by the way, you're out of milk.

        Forgive your enemies - it messes with their heads

        My blog | My articles | MoXAML PowerToys | Onyx

        A Offline
        A Offline
        Adriaan Davel
        wrote on last edited by
        #17

        I understand that I should avoid boxing & un-boxing (and I do want to, and I do it everywhere), in this case it's not an option. Bit of a complex scenario I'll have to explain (and the code is part of a 5 000 file solution), but I'm quite irritated that this is disallowed, I thought polymorphism / covariance / contravariance is exactly about this...

        ____________________________________________________________ Be brave little warrior, be VERY brave

        L R 2 Replies Last reply
        0
        • A Adriaan Davel

          I understand that I should avoid boxing & un-boxing (and I do want to, and I do it everywhere), in this case it's not an option. Bit of a complex scenario I'll have to explain (and the code is part of a 5 000 file solution), but I'm quite irritated that this is disallowed, I thought polymorphism / covariance / contravariance is exactly about this...

          ____________________________________________________________ Be brave little warrior, be VERY brave

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #18

          It is, for objects - aka reference-types, not for value-types. C# is really strict on the difference. The posted alternative with the interface does look like it (could) solve your problem. Alternatively, you could decide only to pass objects, and to wrap your ints in a MyInt class.

          I are Troll :suss:

          1 Reply Last reply
          0
          • A Adriaan Davel

            After much painfull and brain numbing reading I still don't understand why its not possible to cast between Action<T> and Action<object>, can anyone please explain this in small words (I currently have the brain of a 5 year old). There was a poem written along time ago by a person dying with lots of pain, he called it 'Brother Pain', I'm about to write a poem called 'Brother Cannot implicitly convert type 'System.Action<T>' to 'System.Action<object>'' An example:

            public class Base
            {
            public Func<object> OnComplete {get;set;}
            public Base(Func<object> onComplete)
            {
            OnComplete = onComplete;
            }
            }
            public class GenericBase<T> : Base
            {
            public GenericBase(Func<T> onComplete) : base(onComplete) //Error
            {
            OnComplete = onComplete; //Error
            }
            }

            ____________________________________________________________ Be brave little warrior, be VERY brave

            modified on Thursday, March 31, 2011 3:22 AM

            R Offline
            R Offline
            Rob Philpott
            wrote on last edited by
            #19

            Because it just can't. If asked questions such as this I like to mutter something about Covariance and Contravariance and wonder off. Usually works in the office environment anyway.

            Regards, Rob Philpott.

            P 1 Reply Last reply
            0
            • A Adriaan Davel

              I understand that I should avoid boxing & un-boxing (and I do want to, and I do it everywhere), in this case it's not an option. Bit of a complex scenario I'll have to explain (and the code is part of a 5 000 file solution), but I'm quite irritated that this is disallowed, I thought polymorphism / covariance / contravariance is exactly about this...

              ____________________________________________________________ Be brave little warrior, be VERY brave

              R Offline
              R Offline
              RobCroll
              wrote on last edited by
              #20

              It's a design issue and it makes sense when you think about it. If you want to use a collection of type object, then use ArrayList. The generic List is a strongly typed version of ArrayList, so if strong typing is not required, use ArrayList.

              "You get that on the big jobs."

              1 Reply Last reply
              0
              • L Lost User

                Adriaan Davel wrote:

                this object x = 1; works

                That wraps your value-type with a reference-type; your number is actually stored in the object, but a number is not an object itself.

                I are Troll :suss:

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

                In .net, everything is an object. :-D

                L 1 Reply Last reply
                0
                • R Rob Philpott

                  Because it just can't. If asked questions such as this I like to mutter something about Covariance and Contravariance and wonder off. Usually works in the office environment anyway.

                  Regards, Rob Philpott.

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

                  Rob Philpott wrote:

                  Covariance and Contravariance

                  I thought those were added in .net 4.

                  R 1 Reply Last reply
                  0
                  • P PIEBALDconsult

                    In .net, everything is an object. :-D

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #23

                    That's one of those generalizations that I loathe. Yes, structs are objects too. ..but that doesn't make 'em interchangeable :)

                    I are Troll :suss:

                    J 1 Reply Last reply
                    0
                    • P PIEBALDconsult

                      Rob Philpott wrote:

                      Covariance and Contravariance

                      I thought those were added in .net 4.

                      R Offline
                      R Offline
                      Rob Philpott
                      wrote on last edited by
                      #24

                      You see, I'd have wondered off by the point anyone questions it... This is what I'm thinking of: http://blogs.msdn.com/b/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx[^]

                      Regards, Rob Philpott.

                      1 Reply Last reply
                      0
                      • L Lost User

                        That's one of those generalizations that I loathe. Yes, structs are objects too. ..but that doesn't make 'em interchangeable :)

                        I are Troll :suss:

                        J Offline
                        J Offline
                        J4amieC
                        wrote on last edited by
                        #25

                        Eddy Vluggen wrote:

                        but that doesn't make 'em interchangeable

                        Yes it does, assuming the container being used to intercahnge them types the variable as object.

                        L 1 Reply Last reply
                        0
                        • J J4amieC

                          Eddy Vluggen wrote:

                          but that doesn't make 'em interchangeable

                          Yes it does, assuming the container being used to intercahnge them types the variable as object.

                          L Offline
                          L Offline
                          Lost User
                          wrote on last edited by
                          #26

                          J4amieC wrote:

                          Yes it does, assuming the container being used to intercahnge them types the variable as object.

                          The keyword here is "assuming", and your assumption is a leaky abstraction :) Reference-types are objects, value-types can be boxed in an reference-type. And no, a namespace isn't an object, it's not even a type. Once you state that everything is an object, people will assume that anything can be used as a base to derive from (since OO is partly about inheriting from existing objects).

                          I are Troll :suss:

                          J 1 Reply Last reply
                          0
                          • L Lost User

                            J4amieC wrote:

                            Yes it does, assuming the container being used to intercahnge them types the variable as object.

                            The keyword here is "assuming", and your assumption is a leaky abstraction :) Reference-types are objects, value-types can be boxed in an reference-type. And no, a namespace isn't an object, it's not even a type. Once you state that everything is an object, people will assume that anything can be used as a base to derive from (since OO is partly about inheriting from existing objects).

                            I are Troll :suss:

                            J Offline
                            J Offline
                            J4amieC
                            wrote on last edited by
                            #27

                            Eddy Vluggen wrote:

                            Once you state that everything is an object, people will assume that anything can be used as a base to derive from

                            Any non-sealed Type can be used as a base to derive from. What's your point?

                            L 1 Reply Last reply
                            0
                            • J J4amieC

                              Eddy Vluggen wrote:

                              Once you state that everything is an object, people will assume that anything can be used as a base to derive from

                              Any non-sealed Type can be used as a base to derive from. What's your point?

                              L Offline
                              L Offline
                              Lost User
                              wrote on last edited by
                              #28

                              J4amieC wrote:

                              Any non-sealed Type can be used as a base to derive from.

                              You can circumvent the impossibility of inheriting a structure by pointing out that it's a sealed class - but that doesn't change the validity of my statement. I took the example of a namespace to prevent the hairsplitting discussion that structs are merely mutilated classes under the hood :)

                              J4amieC wrote:

                              What's your point?

                              That the text "everything is an object" is incorrect. I stated that literally, didn't I? :laugh:

                              I are Troll :suss:

                              P 1 Reply Last reply
                              0
                              • L Lost User

                                J4amieC wrote:

                                Any non-sealed Type can be used as a base to derive from.

                                You can circumvent the impossibility of inheriting a structure by pointing out that it's a sealed class - but that doesn't change the validity of my statement. I took the example of a namespace to prevent the hairsplitting discussion that structs are merely mutilated classes under the hood :)

                                J4amieC wrote:

                                What's your point?

                                That the text "everything is an object" is incorrect. I stated that literally, didn't I? :laugh:

                                I are Troll :suss:

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

                                (Whoops, sorry to have started that. :-O )

                                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