Advertisements
Posted by: jsonmez | December 16, 2010

Using Var + As, a Neat Little Trick

Perhaps this is something everyone already knew about, but I recently came across this little C# combo that solves one of my major outstanding issues with the var keyword.

I consider var to actually be quite a useful language feature to reduce repetition and make your code slightly more flexible for refactoring, but I’ve always had one little problem with it.

What if I want a base class type or interface?

I most often run into this problem when I am working with lists.

Have you ever written some code like this?

var myList = new List<int>();

 

The problem with this code is that we are stuck with the concrete List implementation for our variable myList, because we don’t have a way of specifying that we actually want an IEnumerable to be our reference type.

The solution is so simple that I am a bit surprised I didn’t think of it earlier.

I had always assumed that I just couldn’t use var there and would have to declare the type like so:

IEnumerable<int> myList = new List<int>();

 

But we can actually just use as to keep our var in place if we want to.

var myList = new List<int> as IEnumerable<int>

 

So it’s actually a little more verbose, but I think it is a bit more clear, and it is more consistent if you are using var everywhere else.

There has to be a better use

I’ve been racking my brain trying to come up with more useful ways to use this little combo, but I can’t really seem to come up with anything.

It seems like there has to be something else you could use this combo for.

What do you think?  Any ideas?

Advertisements

Responses

  1. […] var keyword. I consider var to actually be quite a useful language feature to reduce repetition… [full post] jsonmez Making the Complex Simple c#cool stufflanguage 0 0 0 […]

  2. I like it! The only concern I can think of is that you open yourself up to creating a null reference by accident if for whatever reason you make a typo and end up with valid classes but an invalid cast.

    I don’t think it’d cause enough grief to avoid using the trick, though. The expressiveness will pay off.

  3. To avoid any possible typo like Anna mentioned, you can use regular cast which would give a compiler error if you are trying to cast to a wrong type, like:

    var myList = (IEnumerable)new List();

    • Actually, it looks like as will give you a complier error if you try to do an invalid cast. I just tried it and I couldn’t compile.

      • Hmm, it seems so. Interestingly, the following compiles fine but gives a null on runtime:

        var a = new List() as IEnumerable;

        Probably some exceptional case for generics, I’m sure you can find the reason in C# language reference.

  4. It’s cool, but personally I don’t find it that useful. I try not to reuse my variables, so that I am stuck with a particular implementation doesn’t bother me at all.

  5. maybe List isn’t the best example, but I fail to see how this provides value. maybe for interface segregation.
    var mammal = new Human() as IMammal;

    but even then the local instance is encapsulated within an function so the function could return the base type.

    class Human : IMammal
    {
    public IMammal GiveBirth()
    {
    var human = new Human();
    return human;
    }
    }

  6. Pretty nifty. I don’t think I would say that it is more clear that just declaring the type, but it does make sense if you’re using var everywhere else…something I’m still not sure I dig on. Something about declaring types makes me happy.

  7. One of these days, C# developers are going to wake up and collectively realize that they’ve been coding in VB.NET for years!

    First it was var, which is analogous to VB’s Dim. Now, they’ve taken VB’s “As”.

    🙂

    Though, to give credit to C#, while VB can infer:

    Dim myList = New List(Of Integer)

    Or slightly better:

    Dim myList As New List(Of Integer)

    I have to be explicit if I want the type to be an interface:

    Dim myList As IEnumerable(Of Integer) = New List(Of Integer)

    Just thought it was ironic how similar this is to your last example.

    • Dim is a lot different than var though, take a look at this by Scott Hanselman: http://www.hanselman.com/blog/BackToBasicsVarDim.aspx

      • Thanks, that does clarify a few things.

        I usually code with Option Strict On, so in that respect, the behavior of Dim for me appears very much like var.

        I hadn’t really seen a good example of how useful late binding could be until now, though.

  8. @Tom
    not really. var is syntax sugar, added functionality. you can’t do this in C#
    var i;
    i = 1;
    which I believe you can do in VB.

    as allows C# to cast without exception.
    string s = (string)1;
    will throw an exception because an integer is not a string
    string s = 1 as string;
    will set s to null, rather than throw an exception.

    • Yeah, I had to turn off Option Strict in order to do that. In that case, i is assigned the type of Object.

      All this got me doing some digging around and my conclusion is that the VB syntax is centered more around conversions by default. Whereas, C# is centered more on casting:

      Dim s As String = 1

      Will perform an implicit conversion or throw a compiler error if Option Strict is On.

      Dim s As String = CStr(1)

      Will perform a conversion.

      To emulate the C# behavior:

      Dim t As String = TryCast(1, String)
      Dim s As String = DirectCast(1, String)

      Both throw a compiler error.

      Dim i
      i = 1

      Dim t As String = TryCast(i, String)
      Dim s As String = DirectCast(i, String)

      Again, i is an Object.
      The TryCast will assign Nothing to t, similar to “as” in C#.
      The DirectCast will throw an InvalidCastException., similar to C#.

      Quite interesting. I can see where this can trip people up when having to switch between the two languages.

  9. I fail to see the benefit (other than being overly defensive) of this.

    You’re obviously working inside a class that you’re writing. If you want your client to receive an IEnumerable, that’s exactly what you should give them.

    class MyClass{

    public IEnumerable<string> DoWork(){
    var strings = new List<string>() /*as IEnumerable. why?*/;

    return strings;
    }
    }

    • Fair enough, he is the reason why it is important. Mind you, it is not a very strong reason, but I feel like it at least makes sense.

      Many times some code outside of your control passes you a List directly.
      You want to make sure that you are not modifying that list, because it is an internal storage for the class you got it from.
      In that case you really want your reference to be IEnumberable, so when you do the assignment you need to specify.

      If you can return an IEnumerable, I agree do it. But sometimes you are stuck working with with working with a return value someone else has set up.

  10. I see what you’re saying. But… 😛

    In the above scenario, *you* are the consumer. And what you decide to do doesn’t affect anyone but you.

    I have to admit that I’ve never used the as op with var. I never even thought of it before. I’m sure I’ll find a use for it someday. Thanks! 🙂

  11. That’s the dumbest thing I ever saw

    • Well, you are certainly entitled to your opinion… and who knows perhaps you are right.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: