Type alias in C#

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • peter.tornqvist@gmail.com

    Type alias in C#

    Maybe I'm stupid or maybe I am missing the obvious, but I can't find a way
    to define a type alias in C# for primitive types (class and interfaces I can
    inherit from, no problem). I.e I want to declare a type that is an alias
    for, say, int. Conceptually, this is what I want to do:

    public MyIntType = int; // won't compile

    Anyone knows how to do this?

    --
    Regards, Peter


  • Marc Gravell

    #2
    Re: Type alias in C#

    On a class-file -by- class-file basis you can use (at the top)

    using MyIntType = System.Int32;
    I.e I want to declare a type that is an alias for, say, int
    Well, which do you want to declare: a type or an alias? They are mutually
    exclusive. You can't subclass a struct, however.

    Marc


    Comment

    • peter.tornqvist@gmail.com

      #3
      Re: Type alias in C#

      Well, which do you want to declare: a type or an alias? They are mutually
      exclusive. You can't subclass a struct, however.
      What is the difference in C#? In Delphi (where I have the most experience),
      you create an alias by doing:

      type
      MyIntType = integer;

      and a new type deriving from another type with:

      type
      MyIntType = type integer;

      I'd be interested knowing the different options available in C#

      --
      Regards, Peter


      Comment

      • Marc Gravell

        #4
        Re: Type alias in C#

        Well, in the "class" case, the two syntax demos would be

        using SomeAlias = Full.Namespace. To.BaseClass;

        vs.

        class SomeClass : BaseClass {}

        A: The first (alias) is purely a compiler trick *within a single source
        file*, to allow two things:
        1: (more commonly) to avoid name conflicts within a file without having to
        use fully qualified names, e.g. you have a custom class called (bizarrely)
        XmlDocument, and you are using System.Xml, so you might alias one of the two
        (or both), e.g.
        using MyXmlDocument = My.Namespace.Xm lDocument;

        this now means that in your class file you can use
        MyXmlDocument doc = new MyXmlDocument() ;
        etc without the risk of conflicts, *but* the compiled IL only knows about
        My.Namespace.Xm lDocument.

        2: (less common) to allow the programmer to change the backing type.
        Sometimes generics can help, but note that generics do not respect
        arithmetic (or other) operators. So if you weren't sure if you needed long
        or int, you could use
        using SomeAlias = System.Int32;
        and then
        SomeAlias value = 0;
        value += 5;
        etc
        And if you change your mind later you can change just the alias to Int64.
        *If* all the operations are still supported, then it will compile and work,
        (but may break your interfaces).

        B: the second (inheritance) defines a new type in your assembly inherited
        from the old. This will allow automatic casting in one direction only, and
        *possibly* won't change the behaviour significantly, but is not a good idea.
        As well as being messy, it won't work with interface, static, sealed,
        struct, etc.

        Marc


        Comment

        • Christopher Ireland

          #5
          Re: Type alias in C#

          "Marc Gravell" <marc.gravell@g mail.comwrote in message
          news:OTfnXKnAHH A.1224@TK2MSFTN GP04.phx.gbl...
          B: the second (inheritance) defines a new type in your assembly inherited
          from the old. This will allow automatic casting in one direction only, and
          *possibly* won't change the behaviour significantly, but is not a good
          idea. As well as being messy, it won't work with interface, static,
          sealed, struct, etc.
          It also won't work with value types (System.Double, System.Int, System.Array
          etc.) as they cannot be inherited from. The OP was talking about the [very
          nice] Delphi language feature called 'type identity' which means the ability
          to create a completely new value type based on one of the existing value
          types. AFAIK, this can't be done in C#; you're stuck with using only the
          predefined value types.

          Chris.


          Comment

          • Marc Gravell

            #6
            Re: Type alias in C#

            He asked what the options were; I thought I laid out the options, and yes:
            you are right: none of them include what he wants to do. But I never implied
            that they would.

            Out of interest, what (in Delphi) does this give you? It's been quite a
            while since my last object-pascal days... can you add methods etc? If so,
            then (looking to the future) possibly the C# 3.0 extension functions may be
            of interest. But no use today.
            It also won't work with value types...
            Hence "struct" in that list.

            Perhaps the "other other" alternative is to declare a struct that
            encapsulates the required type, and provide an implicit cast operator in
            both directions, plus any other operators etc that are needed (oh for some
            static inheritance ;-p). A bit more messing than the OP would no-doubt want
            (coming from the Delphi route), but achievable. I've done it many times.

            Oh, and System.Array is a reference type.

            Marc


            Comment

            • Carl Daniel [VC++ MVP]

              #7
              Re: Type alias in C#

              Marc Gravell wrote:
              He asked what the options were; I thought I laid out the options, and
              yes: you are right: none of them include what he wants to do. But I
              never implied that they would.
              >
              Out of interest, what (in Delphi) does this give you? It's been quite
              a while since my last object-pascal days... can you add methods etc?
              If so, then (looking to the future) possibly the C# 3.0 extension
              functions may be of interest. But no use today.
              In a nutshell, it gives you the same thing that having Enums be distinct
              types gives you - better error detection at compile time since mixing values
              and variables from different domains without coersion will cause errors.

              -cd


              Comment

              • Peter Thornqvist

                #8
                Re: Type alias in C#

                Thanks, Marc and Cristopher.

                It's funny how MS has gone from typedef'ing everything in sight in C/C++ to
                creating a language that doesn't allow it at all. This isn't critical to me,
                but it would have been nice to be able to define something like

                public Hwnd = IntPtr;

                to make it more obvious what is expected when declaring method parameters
                and interop signatures.

                --
                Regards, Peter


                Comment

                • Marc Gravell

                  #9
                  Re: Type alias in C#

                  Cheers - good explanation

                  [drifts back over projects past... ahh... now I remember ;-p]

                  Marc


                  Comment

                  • Christopher Ireland

                    #10
                    Re: Type alias in C#

                    "Marc Gravell" <marc.gravell@g mail.comwrote in message
                    news:euOpAcoAHH A.4256@TK2MSFTN GP04.phx.gbl...
                    He asked what the options were; I thought I laid out the options, and yes:
                    you are right: none of them include what he wants to do. But I never
                    implied that they would.
                    OK.
                    Out of interest, what (in Delphi) does this give you?
                    The ability to easily define your own value types.
                    >It's been quite a while since my last object-pascal days... can you add
                    >methods etc?
                    Not using that particular syntax route, no.
                    >If so, then (looking to the future) possibly the C# 3.0 extension
                    >functions may be of interest. But no use today.
                    Possibly.
                    >It also won't work with value types...
                    Hence "struct" in that list.
                    Not all value types are structures, for example, enum.
                    Perhaps the "other other" alternative is to declare a struct that
                    encapsulates the required type, and provide an implicit cast operator in
                    both directions, plus any other operators etc that are needed (oh for some
                    static inheritance ;-p). A bit more messing than the OP would no-doubt
                    want (coming from the Delphi route), but achievable. I've done it many
                    times.
                    Sure you can. Hey, we could all program in assembly and notepad ;-)
                    Oh, and System.Array is a reference type.
                    Yup, you're right. You can't inherit from it though.

                    Chris.


                    Comment

                    • Marc Gravell

                      #11
                      Re: Type alias in C#

                      I never said it was a /fantastic/ option - indeed I only added it as an
                      afterthought.

                      But it can be made to work... if the desire is strong enough.

                      Happy coding ;-p

                      Marc


                      Comment

                      • Dustin Campbell

                        #12
                        Re: Type alias in C#

                        Thanks, Marc and Cristopher.
                        >
                        It's funny how MS has gone from typedef'ing everything in sight in
                        C/C++ to creating a language that doesn't allow it at all. This isn't
                        critical to me, but it would have been nice to be able to define
                        something like
                        >
                        public Hwnd = IntPtr;
                        >
                        to make it more obvious what is expected when declaring method
                        parameters and interop signatures.
                        Peter,

                        Marc mentioned a trick that I've used successfully in the past. Create a
                        new struct called "Hwnd" that is implicitly-convertible to IntPtr by overloading
                        the implicit-conversion operators. This has been especially useful because
                        methods can be added to the Hwnd struct that hide underlying P/Invoke methods.
                        Here's a basic example:

                        public struct HWnd: IWin32Window
                        {
                        // private fields...
                        private IntPtr m_Handle;

                        // constructors...
                        public HWnd(IntPtr handle)
                        {
                        return m_Handle = handle;
                        }

                        // P/Invoke methods...
                        [DllImport("user 32.dll")]
                        private static extern int GetClassName(In tPtr hWnd, [Out] StringBuilder
                        lpClassName, int nMaxCount);

                        // public methods...
                        public string GetClassName()
                        {
                        const int MAX_LENGTH = 256;
                        StringBuilder classNameBuilde r = new StringBuilder(M AX_LENGTH);
                        int count = GetClassName(m_ Handle, classNameBuilde r, MAX_LENGTH);
                        return classNameBuilde r.ToString(0, count);
                        }

                        // IWin32Window properties...
                        public IntPtr Handle { get { return m_Handle; } }

                        // operators...
                        public static implicit operator IntPtr(HWnd hwnd)
                        {
                        return hwnd.Handle;
                        }
                        public static implict operator HWnd(IntPtr ptr)
                        {
                        return new HWnd(ptr);
                        }
                        }

                        Admittedly, there's a bit of extra code but it is a workable solution.

                        Best Regards,
                        Dustin Campbell
                        Developer Express Inc.


                        Comment

                        • Christopher Ireland

                          #13
                          Re: Type alias in C#

                          "Marc Gravell" <marc.gravell@g mail.comwrote in message
                          news:%23DYhFuoA HHA.1196@TK2MSF TNGP03.phx.gbl. ..
                          >I never said it was a /fantastic/ option - indeed I only added it as an
                          >afterthought .
                          OK
                          But it can be made to work... if the desire is strong enough.
                          Yes indeed.
                          Happy coding ;-p
                          Thank you, you too!

                          Chris.


                          Comment

                          • Peter Thornqvist

                            #14
                            Re: Type alias in C#

                            Marc mentioned a trick that I've used successfully in the past. Create a
                            new struct called "Hwnd" that is implicitly-convertible to IntPtr by
                            overloading the implicit-conversion operators. This has been especially
                            useful because methods can be added to the Hwnd struct that hide
                            underlying P/Invoke methods.
                            That is indeed very powerful. Will the HWnd struct be properly
                            wrapped/unwrapped if I used it as parameter in an interop call, i.e if I did
                            this in another class (not in the HWnd struct):
                            public struct HWnd: IWin32Window
                            {
                            ....
                            }

                            public class Win32{

                            [DllImport("user 32.dll")]
                            private static extern int GetClassName(HW nd hWnd, [Out] StringBuilder
                            lpClassName, int nMaxCount);
                            }

                            would the HWnd parameter be correctly interpreted? Is that what the implicit
                            operator declarations does or is there something else as play here?

                            --
                            Regards, Peter


                            Comment

                            • Dave Sexton

                              #15
                              Re: Type alias in C#

                              Hi Christopher,
                              >>It also won't work with value types...
                              >Hence "struct" in that list.
                              >
                              Not all value types are structures, for example, enum.
                              All value-types are structs. Enum is a struct as well.

                              Anything that derives from System.ValueTyp e is a value-type. When you declare
                              a struct in C#, the compiler will ensure that it derives from
                              System.ValueTyp e.

                              System.Enum derives from System.ValueTyp e.

                              Certain classes may expose value-type semantics, such as System.String or
                              custom classes that override Equals, but they are certainly not true
                              value-types in terms of managed memory.

                              --
                              Dave Sexton


                              Comment

                              Working...