Tech Off Thread

17 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

C# using alias and generic types.

Back to Forum: Tech Off
  • User profile image
    eddwo

    I've started using the using alias in C# when I only need a couple of types from a namespace.

    This sort of thing works fine.

    using SValidator = System.Xml.Schema.XmlSchemaValidator;
    using SInfo = System.Xml.Schema.XmlSchemaInfo;

    but is is possible to do it with generic types?

    If I only want BindingList<T> from System.ComponentModel, how do I express that?

    This doesn't work.

    using BindingList = System.ComponentModel.BindingList<T>;

    or this

    using BindingList<T> = System.ComponentModel.BindingList<T>;

    or this

    using BindingList = System.ComponentModel.BindingList;

    Do I have to import the whole ComponentModel namespace when I only want to have one generic type?

  • User profile image
    borosen

    eddwo wrote:
    Do I have to import the whole ComponentModel namespace when I only want to have one generic type?


    Why do you mind 'import the whole ComponentModel namespace'?

    Is there any overhead in doing that?

    Not doing so, will the compile work faster?

    Sorry for not having answered your question but adding more...

  • User profile image
    Ambition

    I don't think that works, you will probably have to use the whole namespace.

    Is there a reason you would want to do this?

  • User profile image
    TommyCarlier

    I can think of a problem that occurs when you import the entire namespace: naming conflicts between classes with the same name.

    Here's an example:

    using System.Data;
    using Xceed.Grid;

    DataRow r = ...;

    Since both System.Data and Xceed.Grid (3rd party component) contain a class DataRow, the compiler can't figure out which one I mean. So I have to explicitely type System.Data.DataRow or Xceed.Grid.DataRow.

    But other than that, I don't see a problem, and I usually import entire namespaces.

  • User profile image
    eddwo

    Well it reduces the number of things I'm not interested in that show up in intellisense all the time.  Big Smile

    Other than that I'm not really bothered, it doesn't seem to make a lot of difference to the compile time.

  • User profile image
    Yggdrasil

    TommyCarlier wrote:
    
    using System.Data;
    using Xceed.Grid;

    DataRow r = ...;


    In that case, you can still import the entire namespace but add an alias to it:

    using System.Data;
    using xceed = Xceed.Grid;

    Then just type xceed.DataRow, instead of the whole namespace.
    Very useful when working with Office interop, since you have many duplicate types in Microsoft.Office.Interop.Word, Microsoft.Office.Interop.Excel, etc.

  • User profile image
    Yggdrasil

    eddwo wrote:
    Well it reduces the number of things I'm not interested in that show up in intellisense all the time. 


    I actually like that - a lot of what I know about the framework comes from wandering about the narrow corridors of Intellisense to see what comes up. It's a wonderful tool to explore the framework.

  • User profile image
    eddwo

    I prefer the object browser for that.

  • User profile image
    weeble

    The reason you'd want to do this would be to allow you to write the same code as if you'd done a "using" on the whole namespace, but leaving a clear "trail of breadcrumbs" back to the type itself. If I write:

    using library1.gizmos;
    using amazing.doodads;
    using yet.another.library.doohickeys;

    //...

    class Example
    {
        Thingummy<float> myThing;
    }

    It's not clear where "Thingummy" comes from without relying on IDE features, and it's even less clear what I'm using from each of the namespaces. Whereas, if I can do this:

    using Frobnicator = library1.gizmos.Frobnicator;
    using SuperDoodad = amazing.doodads.SuperDoodad;
    using Thingummy = yet.another.library.doohickeys.Thingummy;

    //...

    class Example
    {
        Thingummy<float> myThing;
    }

    It becomes clearer where Thingummy comes from, *and* it becomes clear precisely what I'm using out of those namespaces.

    Sometimes you use so much stuff from a namespace and it's so clear that you are best to use the entire namespace. Sometimes you use so few things that you might as well just fully specify them in the few places you use them. However, I find that many things fall in between these extremes, and it's frustrating that this only works so long as I'm not using generics.

  • User profile image
    JoshB

    eddwo wrote:
    Well it reduces the number of things I'm not interested in that show up in intellisense all the time. 



    Agreed. I wish there was a way to configure what was displayed.

  • User profile image
    JChung2006

    Better not to confuse the issue with IronPython.

    That import statement you described is more like reflecting on the generic List type and creating a Type variable named l pointing to that than a using statement.

  • User profile image
    odujosh

    Iron Python allow partial imports (read using):

    import clr
    clr.AddReference("System.Data")
    from System.Data import DataRow as TableDataRow

    from System.Collections.Generic import List as l


    So doing partial imports (using) is possible via the DLR. 

    By C# spec non type specified aliasing is not allowed in C# 2.0 (I quote everything below from there):

    20.5.8 Using alias directives

    Using aliases may name a closed constructed type, but may not name a generic type declaration without

    supplying type arguments. For example:

    namespace N1

    {

    class A<T>

    {

    class B {}

    }

    C# 2.0 SPECIFICATION

    28 Copyright Microsoft Corporation 1999-2003. All Rights Reserved.

    class C {}

    }

    namespace N2

    {

    using W = N1.A; // Error, cannot name generic type

    using X = N1.A.B; // Error, cannot name generic type

    using Y = N1.A<int>; // Ok, can name closed constructed type

    using Z = N1.C; // Ok

    }

    ## End quote of C# 2.0 Spec

    In short when in doubt read the spec as your party may vary.
     

     

  • User profile image
    odujosh

    JChung2006 wrote:
    

    Better not to confuse the issue with IronPython.

    That import statement you described is more like reflecting on the generic List type and creating a Type variable named l pointing to that than a using statement.



    But the point is it could be possible with a using. A decision was made to limit it in C#. I am interested in why. I mean the hit would be taken at compile time since Generics are resolved then in the C#. (List<int> is resolved to one class and List<string> another as specilization of generic classes are needed during the compile process.) I understand that Iron Python allows line by line running of code so this may muddie the waters a bit.

    The nongeneric example of doing semantically the same thing with a non generic was shown earlier in the thread. I am curious why the line was drawn where it was. It certainly is possible in IL as Iron Python proves is this a DLR feature that is limited in the CLR? Sorry for confusing my terms using CLR (Common Language Runtime) instead of DLR (Dynamic Language Runtime).

    Visual Basic seems to not have equal limatation from what I can tell from looking at the spec.  Very interesting.

  • User profile image
    JChung2006

    odujosh wrote:
    
    JChung2006 wrote:
    

    Better not to confuse the issue with IronPython.

    That import statement you described is more like reflecting on the generic List type and creating a Type variable named l pointing to that than a using statement.

    The nongeneric example of doing semantically the same thing with a non generic was shown earlier in the thread.

    No, it isn't.  One is a doing a compile-time type resolution (C# using); the other is doing a run-time type resolution (Python import).  There's a difference, subtle but it's there.

  • User profile image
    odujosh

    JChung2006 wrote:
    
    odujosh wrote:
    
    JChung2006 wrote:
    

    Better not to confuse the issue with IronPython.

    That import statement you described is more like reflecting on the generic List type and creating a Type variable named l pointing to that than a using statement.

    The nongeneric example of doing semantically the same thing with a non generic was shown earlier in the thread.

    No, it isn't.  One is a doing a compile-time type resolution (C# using); the other is doing a run-time type resolution (Python import).  There's a difference, subtle but it's there.


    Visual Basic seems to not have equal limatation from what I can tell from looking at the spec.  Very interesting

  • User profile image
    JChung2006

    In VB 2005,

    Imports GenericList = System.Collections.Generic.List(Of T)

    does not work, but

    Imports StringList = System.Collections.Generic.List(Of String)

    does.

    In IronPython 2.0A6,

    from System.Collections.Generic import List as GenericList

    works by creating a Python type for the generic list from which you can do this:

    >>> StringList = GenericList[str]
    >>> StringList
    <type 'List[str]'>
    >>> list = StringList()
    >>> list
    <List[str] object at 0x0000...>
  • User profile image
    ACD

    I'd like to second that this limitation is bad design.  I'd be happy with:
    using list = System.Collections.Generic.LinkedList;
    or even:
    using list<X> = System.Collections.Generic.LinkedList<X>;

    But I am relegated to:
    using whydoescshavetheseweirdrestrictions = System.Collections.Generic;

    Then: new whydoescshavetheseweirdrestrictions.LinkedList<X>()
    Rather than the much simpler: new list<X>()

    You can do this with the more powerful language F#. 

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.