02 Aug What is LINQ in C#? ASIMplify
Hi, this is Khawaja Asim and this module is the story of LINQ and C#.
LINQ Stands for
Language Intergraded Query. And in this blog post, we’ll explore the features added to the C# language to facilitate LINQ.
Features of LINQ
Features like Lambda expressions and Extension methods, as well as how to write Quires in C#.
LINQ is a technology that gives you the ability to query data from the C# language. And by data, I mean you can query objects that are In-Memory on the heap, objects you’ve persisted into a database, objects behind web services, objects in XML, objects anywhere there’s a LINQ provider.
And every application needs to query data, even if the query is only sorting some existing objects you already have on hand. To do this LINQ provides over 50 Query Operators that you can use. These Operators handle everything from Sorting, Joining, Grouping, Partitioning, Projecting, and of course, Filtering, so you can filter and find just the data that you want.
For instance, if you have a collection of employees, you might want to find just the employees who are Engineers.
So the first hurdle to overcome when building Query Features into a statically typed language like C#, where every object has a definite type, is what we’ll provide these Query Features?
the LINQ Operators are defined as methods. And we know that methods have to be associated with a type. So if we want a method named, Where, which will act like a SQL WHERE Clause to filter data, take an input sequence and return some sort of subset of that, that is the output sequence, then on what type will this method appear? Now since LINQ is supposed to support a variety of data-sources, everything from In-Memory data to data that is inside of a database.
Imagine if we defined a new type, an interface type called ISequence
The drawback here is to that to implement this properly then ISequence
And the big problem here is that if Microsoft wants to introduce new Operators over time, as they have done, then that’s going to break any existing clients that have implemented that interface.
We’ve learned in this class that when you implement an interface you have to provide all the members of that interface in your class definition. If not, it is a compiler error.
So when someone adds a new method, or a new field, or a new property to an interface, you have to change your code and recompile in order to get things working. So adding a method can break an existing client. And this makes this interface approach a little bit tricky. And ultimately Microsoft decided not to define a new type to hold all of these LINQ Operators.
That approach is just not flexible enough, it’s not scalable enough, it doesn’t support change over time. Instead, Microsoft took a different approach and added a new feature to the C# language. When selecting a type to use as the lowest level data source for LINQ, Microsoft selected an existing type from the framework class library. They type IEnumerable
GetEnumerator returns an object that will let you step through data one at a time like you would do in a foreach loop. So I can take this IEnumerable
You can only loop through the data source. But instead of defining new methods on this IEnumerable
DateTime is defined as a struct and structs are implicitly sealed, meaning it is illegal to create a new class that tries to derive from DateTime. You cannot inherit from a sealed class. Inheritance then is not an option for adding methods to DateTime. Which is unfortunate, because sometimes I want to add some additional methods that perform calculations on a DateTime and reuse that code throughout the rest of an application.
For example, given a date like (2002, 8, 9), I want to find out how many days are left in the current month.
There is a way to do this using DateTime.DaysInMonth, but if I want to shorten up that code so that I don’t see the calculation everywhere and actually give it a named method, then my only option is a static method on a static class. We’ll call it DaysTillEndOfMonth. And it’s invoked by using DateUtilities.DaysToEndOfMonth. A static method invocation makes this code a little hard to read, because the type name DateUtilities gets in the way. If I make DaysTillEndOfMonth an extension method, however, I can make this method appear as if it’s an instance method of DateTime. And the way to make an extension method is to add to this keyword in front of the first parameter of a static method on a static class. Now anywhere that I have a DateTime, and this extension method is in scope.
which means the namespace where that extension method appears is either the same as the namespace on the end or it’s including with the USING Clause. I can walk up to a date and I can say, DaysToEndOfMonth. That’s an extension method. You can see it has a slightly different icon here in the IDE.
The IDE is telling you it’s an extension method, but it is invoked now like an instance method because I know longer have to pass the date in as the first parameter.
Extension methods are just a complier trick. DaysToEndOfMonth is not really an instance method. And behind the scenes, the C# compiler will still generate code to call the static method on the static class and pass in that date as the first parameter, but the syntax is much easier to read.