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. Constraints taking either types in generics

Constraints taking either types in generics

Scheduled Pinned Locked Moved C#
help
11 Posts 7 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.
  • D dashingsidds

    Hi Experts, In generics we can give constraints using the "where" clause like

    public void MyGeneric <T>() where T : MyClass1 {...}

    Now if i want the type T to be of type MyClass1 and say an interface IMyInterface then i need to do something like

    public void MyGeneric <T>() where T : MyClass1, IMyInterface {...}

    But I dont know (or maybe it is not possible) if we can create a generic method that can take types which inherits from either of the 2 types. i.e. if any of my other classes inherits from MyClass1 or implements IMyInterface but neither of my class has both then my generic method should work for these classes. I hope I have been clear. Please help! Thanks in advance! Regards, Samar

    K Offline
    K Offline
    kapax5
    wrote on last edited by
    #2

    I think you cannot do that. But, on the other hand, I see no reason to do that, too. If either of the two types works for you, then they must have some common interface. So, all you have to do is to have both MyClass1 and IMyInterface implement some IGeneralInterface.

    D 1 Reply Last reply
    0
    • D dashingsidds

      Hi Experts, In generics we can give constraints using the "where" clause like

      public void MyGeneric <T>() where T : MyClass1 {...}

      Now if i want the type T to be of type MyClass1 and say an interface IMyInterface then i need to do something like

      public void MyGeneric <T>() where T : MyClass1, IMyInterface {...}

      But I dont know (or maybe it is not possible) if we can create a generic method that can take types which inherits from either of the 2 types. i.e. if any of my other classes inherits from MyClass1 or implements IMyInterface but neither of my class has both then my generic method should work for these classes. I hope I have been clear. Please help! Thanks in advance! Regards, Samar

      E Offline
      E Offline
      Ennis Ray Lynch Jr
      wrote on last edited by
      #3

      The concern is type. You need to create a common interface that both MyClass1 and IMyInterface can share. Usually MyClass1 will just implment IMyInterface negating the problem.

      Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. I also do Android Programming as I find it a refreshing break from the MS. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost

      1 Reply Last reply
      0
      • D dashingsidds

        Hi Experts, In generics we can give constraints using the "where" clause like

        public void MyGeneric <T>() where T : MyClass1 {...}

        Now if i want the type T to be of type MyClass1 and say an interface IMyInterface then i need to do something like

        public void MyGeneric <T>() where T : MyClass1, IMyInterface {...}

        But I dont know (or maybe it is not possible) if we can create a generic method that can take types which inherits from either of the 2 types. i.e. if any of my other classes inherits from MyClass1 or implements IMyInterface but neither of my class has both then my generic method should work for these classes. I hope I have been clear. Please help! Thanks in advance! Regards, Samar

        L Offline
        L Offline
        Lukasz Nowakowski
        wrote on last edited by
        #4

        You could try to simulate this with inheritance. You could do:

        class MyGenericBase{
            public virtual T DoSomeStuff() { ... }
        }
        
        class MyGeneric : MyGenericBase
            where T : MyClass1
        {
            public override T DoSomeStuff { ... }
        }
        
        class MyGeneric1 : MyGenericBase
            where T : IMyInterface
        {
            public override T DoSomeStuff() { ... }
        }
        

        I'm pretty sure, that you wan't be able to give derived class with the same identifier (but check it, compiler will tell you ;-) ) And question is: "Why would you want to do it?". Seems like your design isn't perfect.

        Don't forget to rate answer, that helped you. It will allow other people find their answers faster.

        1 Reply Last reply
        0
        • K kapax5

          I think you cannot do that. But, on the other hand, I see no reason to do that, too. If either of the two types works for you, then they must have some common interface. So, all you have to do is to have both MyClass1 and IMyInterface implement some IGeneralInterface.

          D Offline
          D Offline
          dashingsidds
          wrote on last edited by
          #5

          I knew this would come. But my problem here is the class MyClass1 in my case is a .net class and i cannot modify it to make it implement an interface. Thanks for your time kapax5. Regards, Samar

          L 1 Reply Last reply
          0
          • D dashingsidds

            I knew this would come. But my problem here is the class MyClass1 in my case is a .net class and i cannot modify it to make it implement an interface. Thanks for your time kapax5. Regards, Samar

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

            unless the .NET class is sealed, you could derive from it and make that implement the interface of your choice. :)

            Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

            Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

            K 1 Reply Last reply
            0
            • L Luc Pattyn

              unless the .NET class is sealed, you could derive from it and make that implement the interface of your choice. :)

              Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

              Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

              K Offline
              K Offline
              kapax5
              wrote on last edited by
              #7

              Yes, a very good note. I am pretty sure that the author of the question understands why his provided idea is impossible. So, something must be done with inheritance, or maybe if we knew what exactly he is trying to do, we could find a workaround for the problem.

              1 Reply Last reply
              0
              • D dashingsidds

                Hi Experts, In generics we can give constraints using the "where" clause like

                public void MyGeneric <T>() where T : MyClass1 {...}

                Now if i want the type T to be of type MyClass1 and say an interface IMyInterface then i need to do something like

                public void MyGeneric <T>() where T : MyClass1, IMyInterface {...}

                But I dont know (or maybe it is not possible) if we can create a generic method that can take types which inherits from either of the 2 types. i.e. if any of my other classes inherits from MyClass1 or implements IMyInterface but neither of my class has both then my generic method should work for these classes. I hope I have been clear. Please help! Thanks in advance! Regards, Samar

                C Offline
                C Offline
                Covean
                wrote on last edited by
                #8

                In some situations I also think it would be nice to have this possibility. But take this example:

                public void MyGeneric<T>(T tValue) where T : InterfaceA | InterfaceB
                {
                tValue.<what>(); //<- and here is the problem - What interface do I access InterfaceA or InterfaceB?
                }

                I hope you see where your logical mistake lies.

                Greetings Covean

                P 1 Reply Last reply
                0
                • D dashingsidds

                  Hi Experts, In generics we can give constraints using the "where" clause like

                  public void MyGeneric <T>() where T : MyClass1 {...}

                  Now if i want the type T to be of type MyClass1 and say an interface IMyInterface then i need to do something like

                  public void MyGeneric <T>() where T : MyClass1, IMyInterface {...}

                  But I dont know (or maybe it is not possible) if we can create a generic method that can take types which inherits from either of the 2 types. i.e. if any of my other classes inherits from MyClass1 or implements IMyInterface but neither of my class has both then my generic method should work for these classes. I hope I have been clear. Please help! Thanks in advance! Regards, Samar

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

                  I'm not sure what you mean. MyClass1 doesn't need to implement IMyInterface -- as long as the provided class does and derives from MyClass1.

                  public class Base
                  {
                  }

                  public class Derived : Base , System.IDisposable
                  {
                  public void
                  Dispose
                  (
                  )
                  {
                  }
                  }

                  public class Generic<T> where T : Base , System.IDisposable
                  {
                  }

                  var x = new Generic<Derived>() ;

                  1 Reply Last reply
                  0
                  • C Covean

                    In some situations I also think it would be nice to have this possibility. But take this example:

                    public void MyGeneric<T>(T tValue) where T : InterfaceA | InterfaceB
                    {
                    tValue.<what>(); //<- and here is the problem - What interface do I access InterfaceA or InterfaceB?
                    }

                    I hope you see where your logical mistake lies.

                    Greetings Covean

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

                    That's a very bad idea, but if you need it you can simulate it by providing your own checks.

                    C 1 Reply Last reply
                    0
                    • P PIEBALDconsult

                      That's a very bad idea, but if you need it you can simulate it by providing your own checks.

                      C Offline
                      C Offline
                      Covean
                      wrote on last edited by
                      #11

                      What do you mean is a very bad idea, to have this 'OR' constraint? I don't think so. Take a look at this example: Lets say you want to add an extention to the values types short, int, long.

                      public static class ValueTypeExtention
                      {
                      // A
                      public static ulong ToUnsignedLongUnchecked(this T signedValue) where T : IConvertible
                      {
                      return signedValue.ToUInt64();
                      }

                      // B
                      public static ulong ToUnsignedLongUnchecked(this T signedValue) where T : struct { ... }
                      
                      // C
                      public static ulong ToUnsignedLongUnchecked(this short signedValue) { return signedValue.ToUInt64(); }
                      public static ulong ToUnsignedLongUnchecked(this int signedValue) { return signedValue.ToUInt64(); }
                      public static ulong ToUnsignedLongUnchecked(this long signedValue) { return signedValue.ToUInt64(); }
                      
                      // D
                      public static ulong ToUnsignedLongUnchecked(this T signedValue) where T : short | int | long
                      {
                          return unchecked((ulong)signedValue);
                      }
                      
                      // E
                      public static ulong ToUnsignedLongUnchecked(this T signedValue) where T : (short | int | long) as IConvertible
                      {
                          return signedValue.ToUInt64();
                      }
                      

                      }

                      A, B and C are versions how you could solve this problem nowadays. But lets have a deeper look: - A allows bool bValue=false; ulong ulVal = bValue.ToUnsignedLongUnchecked();. It allows it for every class/struct that implements IConvertible. - B needs type checking and offers ToUnsignedLongUnchecked() to every struct even BITMAPINFO. - C is the only way to solve the condition completely but needs multiple implementations. Using where T : struct, IConvertible as constraints is the best way to solve this problem with generics so far. The 'pseudo' constraint D just allows T to be one of this 3 value types. And I think E could be the best way.

                      Greetings Covean

                      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