Bnei Brak 51202 Israel LINQ to Objects • Using language integrated query operators with objects • Customizing query operators for particular objects • Examples, examples, examples... LIN
Trang 1LINQ via C# 3.0
Chapter 4 – LINQ to Objects
Trang 2© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel
LINQ to Objects
• Using language integrated query operators with objects
• Customizing query operators for particular objects
• Examples, examples, examples
Trang 3LINQ to Objects
• LINQ to Objects relies on the
Enumerable class, which contains query operators as extension methods
• Any IEnumerable<T> can be queried
• Additional types can be queried if they
implement the query pattern
Trang 4© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel
Query Pattern
• If the type is not IEnumerable, there are
two ways to make it queryable:
– Add instance methods for query operators:
Select<T>, Where, OrderBy, etc.
– Add extension methods in a separate class for query
operators: Select<T>, Where, OrderBy, etc.
Trang 5Query Pattern: Select
class PayrollSystem {
public IEnumerable<T> Select<T>(
Func<Employee,T> selector) {
return employees.Select(selector);
}
internal List<Employee> employees
= ;
//More implementation omitted
}
PayrollSystem payroll = ;
var names = from employee in payroll
select employee.Name;
Trang 6© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel
Query Pattern: Select Extension
• Alternatively, an extension method can be used:
class PayrollSystem {
internal List<Employee> employees = ;
//More implementation omitted
}
static class PayrollExtensions {
public static IEnumerable<T> Select <T>(
this PayrollSystem payroll,
Func<Employee,T> selector) {
return payroll.employees.Select(selector);
}
}
PayrollSystem payroll = ;
var names = from employee in payroll
select employee.Name;
Trang 7Query Pattern: Where
class PayrollSystem {
public IEnumerable<Employee> Where(
Func<Employee,bool> filter) {
return employees.Where(filter);
}
internal List<Employee> employees
= ;
//Select<T> omitted
}
PayrollSystem payroll = ;
var names = from employee in payroll
where employee.Salary > 220
select employee.Name;
Trang 8© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel
Feature Notes
• The query pattern implementation can also
be used to customize query behavior
– For example, specify additional filters for the Where
query operator (even if the object is IEnumerable)
static class PayrollExtensions {
public static IEnumerable<Employee>
Where(
this PayrollSystem payroll,
Func<Employee,bool> filter) {
return payroll.employees.Where(
e => e.City==“London” &&
filter(e));
}
}
Trang 9LINQ to Objects Applicability
• Any object model is a potential data
source for LINQ queries
– The requirements are not strict – either
IEnumerable or the query pattern
• Make your object models LINQ-friendly!
Trang 10© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel
LINQ to Strings
string s = Guid.NewGuid().ToString();
string digitsOnly =
new string((from c in s
where Char.IsDigit(c)
select c)
.ToArray());
Console.WriteLine(s + “\n” + digitsOnly);
//Output:
8faf837d-f0a6-4e69-8ac5-23635452f6f9
883706469852363545269
Trang 11LINQ to Reflection
//Find all collection-initializable types
//(Rough sketch)
var queryableTypes =
from asm in
AppDomain.CurrentDomain.GetAssemblies()
from t in asm.GetExportedTypes()
where t.GetInterfaces().Any(itf =>
itf.IsGenericType &&
((itf.IsGenericTypeDefinition
&& itf == typeof(ICollection<>)) ||
(!itf.IsGenericTypeDefinition &&
itf.GetGenericTypeDefinition() ==
typeof(ICollection<>)))
) ||
typeof(IEnumerable).IsAssignableFrom(t) &&
t.GetMethods().Any(m => m.Name == "Add")
select t;
Trang 12© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel
LINQ to File System
//Find all large DLLs in System32
var largeDllFiles =
from file in Directory.GetFiles(
Environment.GetFolderPath(
Environment.SpecialFolder.System))
let info = new FileInfo(file)
where info.Extension == ".dll" &&
info.Length > 5000000
select info.FullName;
Trang 13LINQ to WCF Contracts
var operations =
from operation in
ContractDescription.GetContract(
typeof(IService)).Operations
where !operation.IsOneWay
where operation.Faults.Any(
f => f.DetailType == typeof(string))
select new {
operation.DeclaringContract.Namespace,
operation.SyncMethod.Name
};
Trang 14© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel
LINQ to Objects Performance
1 Don’t turn every for and foreach loop
into a LINQ query
2.yield return is often slower than
hand-rolled enumerators or for loops
3 Invoking lambdas is often more
expensive than an inline loop body
4 Measure to ensure sane results and sane
number of calls (run-time complexity)
Trang 15Chapter Summary
• Using language integrated query operators with objects
• Implementing the query pattern for
non-IEnumerable objects
• Customizing the query behavior for
specific objects