Tech Off Thread

11 posts

Forum Read Only

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

C# - Implicitly typed local variables

Back to Forum: Tech Off
  • User profile image
    Larsenal

    I've watched this video on LINQ in C#.  If the type is set at compile time, what's the benefit of using the "var" keyword?  It seems like it just makes the code less readable.

    I look at the first example here, and wonder why not just replace the var with string[]?

    Anyone have any ideas?

  • User profile image
    mabster

    Perhaps the "var" keyword makes it easier to parse, if you want the type to be implicitly discovered.

    But yeah, since you know what you're searching for, it would seem to make more sense to explicitly define the result set type, if that's possible.

  • User profile image
    Tyler Brown

    I'd prefer to set the type myself... but the var keyword would be required (at the very least, of course declaring it as a type yourself could be used in place, if allowed) in order to provide some sort of variable declaration. Without the var keyword (or any type definition) the compiler would simply see any undefined variable as a local variable... which would of course have some nasty side-effects with some hard to track down bugs I'd assume.

  • User profile image
    wacko

    I think it could be useful maybe if you wanted to change types without having to cast... Something like the following

    string[] aBunchOfWords = {"One","Two", "Hello",
    
      "World", "Four", "Five"};
                int[] aBunchOfNumbers = {1,2,3,4,5,6};
    
        
    
            var result =
                from s in aBunchOfWords // query the string array
               
    where s.Length == 5     // for all words with
    length = 5
               
    select
    s;              
    // and return the string
    
                foreach (var i in result)
                {
                    Console.WriteLine(i);
                }
                Console.ReadLine();
    
                result = 
                    from v in aBunchOfNumbers
                    select v + 1;
    
                foreach (var i in result)
                {
                    Console.WriteLine(i);
                }
                Console.ReadLine();
    


    this code does not work because for what ever reason the first result complains about a where<string>.
    I also think in the sence of relational Data the whole LINQ project makes things much easier.  But I could see var being better utilized if we could do more with it.

  • User profile image
    wacko

    I had to post this, which was Cyrus Blather's explantion for why var is around, and this is a direct quote from his blog,

    "Well, "var" is are way of introducing "local variable type inference".  It's a new C# 3.0 feature that allows you to save space by not writing the type of a local variable"

    thats right... to save space

  • User profile image
    trolane

    var can simply be thought of as a set once variant.

  • User profile image
    Dan

    This is a good question Big Smile

    There are two reasons. As stated earlier, it's shorthand for defining a type, but the big reason in my opinion is that LINQ enables you to create or "project" wholly new data types without having to create the type themselves. This is known as projection.

    Let's look at my first example:

    var result =
    from s in aBunchOfWords
    where s.Length == 5
    select s;

    In this example, I am projecting the string "s",  so I could have easily replaced var with the type IEnumerable<string> as shown in bold below and my code would have worked fine.

    IEnumerable<string> result =
    from s in aBunchOfWords
    where s.Length == 5
    select s;

    But what if I wanted to project something more complex, like a complex type that contains 
    1) the string
    2) the length of the string as an integer
    3) the first three characters of the substring

    Using the power of var, this is pretty easy as shown in bold below:

    var result =
    from s in aBunchOfWords
    where s.Length == 5
    //Creates a new anonymous type with name/value pairs
    select new {Value=s, Length=s.Length, FirstThreeLetters=s.Substring(0,3)};

    //Print values 
    foreach (var x in result)
    Console.WriteLine("Value: {0}, Length:{1}, SubString:{2}",
    x.Value, x.Length, x.FirstThreeLetters);

    This prints:
    Value: Hello, Length:5, SubString:Hel
    Value: World, Length:5, SubString:Wor

    As you can see, I can use "select new" and project my own custom type with field name/value pairs. Under the covers var infers the field names, field values, and field data types and creates an anonymous type with the three fields I projected.

    Without var, you would have to create the anonymous type yourself, which basically means you have to create a custom class for the type as shown below:

    public class MyType
    {
    public string
    Value;
    public int
    Length;
    public string
    FirstThreeLetters;
    }

    IEnumerable<MyType> result =
    from s in aBunchOfWords
    where s.Length == 5
    select new MyType {Value=s, Length=s.Length, FirstThreeLetters=s.Substring(0,3)};

    While I get the same results as in the previous example, you can see how var saves me the trouble of defining my own type. In the var example, the compiler is creating its own version of the "MyType" class, but you as a LINQ developer don't need to worry about that. If you really don't like var, you can of course manually create your own class and map them to LINQ queries as I showed and everything will still "just work".

    When you're dealing with projection, var is awesome in that it really eliminates the grunt work of defining your own type, which, when you get to nested types can be pretty ugly Smiley

    You can find a whole slew of projection operator samples at: http://msdn.microsoft.com/vcsharp/future/linqsamples/projection/default.aspx


    I hope this helps!
    -Dan

  • User profile image
    JChung2006

    The idea of "var" is to have the compiler infer the type for you without having to do stuff like this:

    MyClass myClass = new MyClass();

    This is necessary if you are going to use another one of C# 3.0's new features which is anonymous types:

    var myAnonymousClass = new { Name = "Lawnmower", Price = 495.00 };

    Edit:  Oops, I basically just posted what Dan did, only more concisely (maybe too concisely -- Dan's explanation is great).

  • User profile image
    Maurits

    Oy.  That's a lot to digest.

    My first reaction was... gee, that looks a lot like Perl.  Despite what the guy said in the video that it was "not to be confused with Perl" because you can't switch types over the life of a variable.

    Given that I like Perl, this is a good thing.  Perl, but strongly typed.  Cool.  There's even a => operator, very Perl.

    Very strange, though.  Not C-like at all.  There's going to be a very steep learning curve here, I think.

  • User profile image
    wacko

    I am glad dan cleared that up, makes much more sense now Smiley:)Smiley

  • User profile image
    Larsenal

    Thanks Dan! Your example illustrated the point quite well.

Conversation locked

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