Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ for beginners

Tags:

c#

linq

I love C#, I love the framework, and I also love to learn as much as possible. Today I began to read articles about LINQ in C# and I couldn't find anything good for a beginner that never worked with SQL in his life.

I found this article very helpful and I understood small parts of it, but I'd like to get more examples.

After reading it couple of times, I tried to use LINQ in a function of mine, but I failed.

    private void Filter(string filename)
    {
        using (TextWriter writer = File.CreateText(Application.StartupPath + "\\temp\\test.txt"))
        {
            using(TextReader reader = File.OpenText(filename))
            {
                string line;
                while((line = reader.ReadLine()) != null)
                {
                    string[] items = line.Split('\t');
                    int myInteger = int.Parse(items[1]);
                    if (myInteger == 24809) writer.WriteLine(line); 
                }
            }
        }
    }

This is what I did and it did not work, the result was always false.

    private void Filter(string filename)
    {
        using (TextWriter writer = File.CreateText(Application.StartupPath + "\\temp\\test.txt"))
        {
            using(TextReader reader = File.OpenText(filename))
            {
                string line;
                while((line = reader.ReadLine()) != null)
                {
                    string[] items = line.Split('\t');
                    var Linqi = from item in items
                                where int.Parse(items[1]) == 24809
                                select true;
                    if (Linqi == true) writer.WriteLine(line); 
                }
            }
        }
    }

I'm asking for two things:

  1. How would the function look like using as much Linq as possible?
  2. A website/book/article about Linq,but please note I'm a decent beginner in sql/linq.

Thank you in advance!

like image 452
Ivan Prodanov Avatar asked May 21 '09 15:05

Ivan Prodanov


1 Answers

Well one thing that would make your sample more "LINQy" is an IEnumerable<string> for reading lines from a file. Here's a somewhat simplified version of my LineReader class from MiscUtil:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

public sealed class LineReader : IEnumerable<string>
{
    readonly Func<TextReader> dataSource;

    public LineReader(string filename)
        : this(() => File.OpenText(filename))
    {
    }

    public LineReader(Func<TextReader> dataSource)
    {
        this.dataSource = dataSource;
    }

    public IEnumerator<string> GetEnumerator()
    {
        using (TextReader reader = dataSource())
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                yield return line;
            }
        }
    }


    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

Now you can use that:

    var query = from line in new LineReader(filename)
                let items = line.Split('\t')
                let myInteger int.Parse(items[1]);
                where myInteger == 24809
                select line;

    using (TextWriter writer = File.CreateText(Application.StartupPath 
                                               + "\\temp\\test.txt"))
    {
        foreach (string line in query)
        {
            writer.WriteLine(line);
        }
    }

Note that it would probably be more efficient to not have the let clauses:

    var query = from line in new LineReader(filename)
                where int.Parse(line.Split('\t')[1]) == 24809
                select line;

at which point you could reasonably do it all in "dot notation":

    var query = new LineReader(filename)
                        .Where(line => int.Parse(line.Split('\t')[1]) == 24809);

However, I far prefer the readability of the original query :)

like image 60
Jon Skeet Avatar answered Oct 08 '22 11:10

Jon Skeet