LINQ is a valuable feature for database and XML programming, but not only. Basically, you can use LINQ with everything that returns an IEnumerable. Here is an example, when I want to list the directories of a parent directory, in alfabetical order, and grouped by the file attributes (first all that have only the flag Directory set, then those that have both ReadOnly and Directory, etc.).
First, let’s try how you would put this clasically in C# 2.0. Basically you need these:
- obtain a list of directory names
- create a sorted dictionary with the key representing the file attributes, and the value a list of directories
- iterate over the list of names and create a DirectoryName object
- add the object to the list corresponding to the key represented by the directory attributes
- iterate over the dictionary and print its content
The code I wrote for that looks like this:
void ClassicList(string path)
{
string [] entries = System.IO.Directory.GetDirectories(path);
SortedDictionary> dic =
new SortedDictionary>();
foreach (string entry in entries)
{
DirectoryInfo dir = new DirectoryInfo(entry);
try
{
dic[dir.Attributes].Add(dir);
}
catch (KeyNotFoundException)
{
dic.Add(dir.Attributes, new List());
dic[dir.Attributes].Add(dir);
}
}
foreach (KeyValuePair> group in dic)
{
Console.WriteLine("Directories with attributes: {0}", group.Key);
foreach (DirectoryInfo dir in group.Value)
Console.WriteLine(" {0}", dir.Name);
}
}
With LINQ, things get much simpler, as you no longer need to create a dictionary. You can apply SQL-like queries on objects. What you have to do is:
- obtain a list of directory names
- create a query to select the directories and group them according to their attributes
- iterate over the result and print the its content
This is how it looks like:
void LinqList(string path)
{
string[] entries = System.IO.Directory.GetDirectories(path);
var result = from dir in
from e in entries select new DirectoryInfo(e)
orderby dir.Name
group dir by dir.Attributes into dirGroups
orderby dirGroups.Key
select dirGroups;
foreach (var group in result)
{
Console.WriteLine("Directories with attributes: {0}", group.Key);
foreach (var dir in group)
Console.WriteLine(" {0}", dir.Name);
}
}
Let’s take the querry line by line and see what it does:
- from dir in from e in entries select new DirectoryInfo(e)creates a DirectoryInfo for each element of entries and uses the resulted array as source
- orderby dir.Nameorders the DirectoryInfo array by the name of the directories
- group dir by dir.Attributes into dirGroupsgroups the directories by their attributes into dirGroups
- orderby dirGroups.Keyorders the group by the key
- select dirGroupsselects the groups
And that’s all. You don’t have to struggle with creating dictionaries, maintaining the correct sorting and so on. You can do all of that with a simple query.
The following listing shows a second query that displays the directories ascending by their creation time, and for each directory the name, creation time and attributes are listed. The code also exemplifies the use of anonymous types, and the inference of the type from the assigned value, concepts new in C# 3.0:
void LinqList2(string path)
{
string[] entries = System.IO.Directory.GetDirectories(path);
var result = from dir in
from e in entries select new DirectoryInfo(e)
orderby dir.CreationTime
select new {
Name = dir.Name,
Attr = dir.Attributes,
Creation = dir.CreationTime };
foreach(var item in result)
{
Console.WriteLine("{0}\n\t{1}\t{2}",
item.Name, item.Creation, item.Attr);
}
}










no comment untill now