C#: Future Directions in C#: Future Directions in Language InnovationLanguage Innovation
Anders HejlsbergAnders HejlsbergTLN307TLN307Technical FellowTechnical FellowMicrosoft CorporationMicrosoft Corporation
The LINQ ProjectThe LINQ Project
StandardStandardQueryQuery
OperatorsOperators
ObjectsObjects
DLinqDLinq(ADO.NET)(ADO.NET)
XLinqXLinq(System.Xml)(System.Xml)
<book> <title/> <author/> <year/> <price/></book>
XMLXML
.NET Language Integrated Query.NET Language Integrated Query
C#C# VBVB Others…Others…
SQLSQL WinFWinFSS
C# 3.0 Design GoalsC# 3.0 Design Goals
Integrate objects, relational, and XMLIntegrate objects, relational, and XML
Build on foundation laid in C# 1.0 and Build on foundation laid in C# 1.0 and
2.02.0
Run on the .NET 2.0 (“Whidbey”) CLRRun on the .NET 2.0 (“Whidbey”) CLR
Don’t tie language to specific APIsDon’t tie language to specific APIs
Remain 100% backwards compatibleRemain 100% backwards compatible
4
Language Integrated QueryLanguage Integrated Query
5
C# 3.0 Language C# 3.0 Language InnovationsInnovations
var contacts =var contacts = from c in customersfrom c in customers where c.State == "WA"where c.State == "WA" select new { c.Name, c.Phone };select new { c.Name, c.Phone };
var contacts =var contacts = customerscustomers .Where(c => c.State == "WA").Where(c => c.State == "WA") .Select(c => new { c.Name, c.Phone });.Select(c => new { c.Name, c.Phone });
Extension Extension methodsmethods
Lambda Lambda expressionsexpressions
Query Query expressionsexpressions
Object Object initializersinitializers
Anonymous Anonymous typestypes
Local Local variable type variable type
inferenceinference
6
public delegate bool Predicate<T>(T obj);public delegate bool Predicate<T>(T obj);
public class List<T>public class List<T>{{ public List<T> FindAll(Predicate<T> test) public List<T> FindAll(Predicate<T> test) { … }{ … } … …}}
Lambda ExpressionsLambda Expressions
List<Customer> customers = List<Customer> customers = GetCustomerList();GetCustomerList();
List<Customer> x = customers.FindAll(List<Customer> x = customers.FindAll( delegate(Customer c) { return c.State == delegate(Customer c) { return c.State == "WA"; }"WA"; }););
List<Customer> x = customers.FindAll(List<Customer> x = customers.FindAll(c => c.State c => c.State == "WA"== "WA"););
ExplicitlyExplicitlytypedtyped
Statement Statement contextcontext
ImplicitlyImplicitlytypedtyped
Expression Expression contextcontext
7
Lambda ExpressionsLambda Expressionspublic delegate T Func<T>();public delegate T Func<T>();public delegate T Func<A0, T>(A0 arg0);public delegate T Func<A0, T>(A0 arg0);public delegate T Func<A0, A1, T>(A0 arg0, public delegate T Func<A0, A1, T>(A0 arg0, A1 arg1);A1 arg1);……
Func<Customer, bool> test = Func<Customer, bool> test = c => c.State c => c.State == "WA"== "WA";;
Func<int, int, int> f = Func<int, int, int> f = (x, y) => x * y(x, y) => x * y;;
Func<int, int, int> comparer =Func<int, int, int> comparer = (int x, int y) => {(int x, int y) => { if (x > y) return 1;if (x > y) return 1; if (x < y) return -1;if (x < y) return -1; return 0;return 0; }};;
double factor = 2.0;double factor = 2.0;Func<double, double> f = Func<double, double> f = x => x * factorx => x * factor;;
8
Queries Through APIsQueries Through APIs
public class List<T>public class List<T>{{ public List<T> Where(Func<T, bool> predicate) { … }public List<T> Where(Func<T, bool> predicate) { … } public List<S> Select<S>(Func<T, S> selector) { … }public List<S> Select<S>(Func<T, S> selector) { … } … …}}
List<Customer> customers = List<Customer> customers = GetCustomerList();GetCustomerList();
List<string> contacts =List<string> contacts = customers.Where(c => c.State == "WA").Select(c customers.Where(c => c.State == "WA").Select(c => c.Name);=> c.Name);
Query operators Query operators are just are just methodsmethods
Type inference Type inference figures out <S>figures out <S>
But what about But what about other types?other types? Declare Declare
operators in all operators in all collections?collections?
What about What about arrays?arrays?
Methods Methods compose to compose to form queriesform queries
9
Queries Through APIsQueries Through APIs
public static class Sequencepublic static class Sequence{{ public static IEnumerable<T> Where<T>(IEnumerable<T> public static IEnumerable<T> Where<T>(IEnumerable<T> source,source, Func<T, bool> predicate) { … }Func<T, bool> predicate) { … }
public static IEnumerable<S> Select<T, public static IEnumerable<S> Select<T, S>(IEnumerable<T> source,S>(IEnumerable<T> source, Func<T, S> selector) { … }Func<T, S> selector) { … } … …}}
Customer[] customers = GetCustomerArray();Customer[] customers = GetCustomerArray();
IEnumerable<string> contacts = Sequence.Select(IEnumerable<string> contacts = Sequence.Select( Sequence.Where(customers, c => c.State == Sequence.Where(customers, c => c.State == "WA"),"WA"), c => c.Name);c => c.Name);
Query operators Query operators are static are static methodsmethods
Huh?Huh?
Want methods Want methods on on
IEnumerable<TIEnumerable<T>>
10
namespace System.Querynamespace System.Query{{ public static class Sequencepublic static class Sequence {{ public static IEnumerable<T> Where<T>(this public static IEnumerable<T> Where<T>(this IEnumerable<T> source,IEnumerable<T> source, Func<T, bool> predicate) { … }Func<T, bool> predicate) { … }
public static IEnumerable<S> Select<T, S>(this public static IEnumerable<S> Select<T, S>(this IEnumerable<T> source,IEnumerable<T> source, Func<T, S> selector) { … }Func<T, S> selector) { … } … … }}}}
Extension MethodsExtension Methods
using System.Query;using System.Query;
ExtensionExtensionmethodsmethods
IEnumerable<string> contacts =IEnumerable<string> contacts = customers.Where(c => c.State == "WA").Select(c customers.Where(c => c.State == "WA").Select(c => c.Name);=> c.Name);
Brings Brings extensions into extensions into
scopescope
obj.Foo(x, y)obj.Foo(x, y)
XXX.Foo(obj, x, XXX.Foo(obj, x,
y)y)
IntelliSense!IntelliSense!
11
Lambda Expressions and Lambda Expressions and Extension MethodsExtension Methods
12
Object InitializersObject Initializers
public class Pointpublic class Point{{ private int x, y;private int x, y;
public int X { get { return x; } set { x = public int X { get { return x; } set { x = value; } }value; } } public int Y { get { return y; } set { y = public int Y { get { return y; } set { y = value; } }value; } }}}
Point a = new Point { X = 0, Y Point a = new Point { X = 0, Y = 1 };= 1 };
Point a = new Point();Point a = new Point();a.X = 0;a.X = 0;a.Y = 1;a.Y = 1;
Field or property Field or property assignmentsassignments
13
Object InitializersObject Initializers
public class Rectanglepublic class Rectangle{{ private Point p1 = new Point();private Point p1 = new Point(); private Point p2 = new Point();private Point p2 = new Point();
public Point P1 { get { return p1; } }public Point P1 { get { return p1; } } public Point P2 { get { return p2; } }public Point P2 { get { return p2; } }}}
Rectangle r = new Rectangle {Rectangle r = new Rectangle { P1 = { X = 0, Y = 1 },P1 = { X = 0, Y = 1 }, P2 = { X = 2, Y = 3 }P2 = { X = 2, Y = 3 }};};
Rectangle r = new Rectangle r = new Rectangle();Rectangle();r.P1.X = 0;r.P1.X = 0;r.P1.Y = 1;r.P1.Y = 1;r.P2.X = 2;r.P2.X = 2;r.P2.Y = 3;r.P2.Y = 3;
Embedded Embedded objectsobjects
No “new No “new Point”Point”
Read-only Read-only propertiesproperties
14
Collection InitializersCollection Initializers
List<int> powers = new List<int> { 1, 10, 100, List<int> powers = new List<int> { 1, 10, 100, 1000, 10000 };1000, 10000 };
Must Must implement implement
ICollection<T>ICollection<T>
List<int> powers = new List<int> powers = new List<int>();List<int>();powers.Add(1);powers.Add(1);powers.Add(10);powers.Add(10);powers.Add(100);powers.Add(100);powers.Add(1000);powers.Add(1000);powers.Add(10000);powers.Add(10000);
15
Collection InitializersCollection Initializers
public class Contactpublic class Contact{{ private string name;private string name; private List<string> phoneNumbers = new List<string>();private List<string> phoneNumbers = new List<string>();
public string Name { get { return name; } set { name = public string Name { get { return name; } set { name = value; } }value; } } public List<string> PhoneNumbers { get { return public List<string> PhoneNumbers { get { return phoneNumbers; } }phoneNumbers; } }}}
List<Contact> contacts = new List<Contact> {List<Contact> contacts = new List<Contact> { new Contact {new Contact { Name = "Chris Smith",Name = "Chris Smith", PhoneNumbers = { "206-555-0101", "425-882-PhoneNumbers = { "206-555-0101", "425-882-8080" }8080" } },}, new Contact {new Contact { Name = "Bob Harris",Name = "Bob Harris", PhoneNumbers = { "650-555-0199" }PhoneNumbers = { "650-555-0199" } }}};};
16
Local Variable Type Local Variable Type InferenceInference
int i = 5;int i = 5;string s = "Hello";string s = "Hello";double d = 1.0;double d = 1.0;int[] numbers = new int[] {1, 2, 3};int[] numbers = new int[] {1, 2, 3};Dictionary<int,Order> orders = new Dictionary<int,Order> orders = new Dictionary<int,Order>();Dictionary<int,Order>();
var i = 5;var i = 5;var s = "Hello";var s = "Hello";var d = 1.0;var d = 1.0;var numbers = new int[] {1, 2, 3};var numbers = new int[] {1, 2, 3};var orders = new Dictionary<int,Order>();var orders = new Dictionary<int,Order>();
““var” means var” means same type as same type as
initializerinitializer
17
Anonymous TypesAnonymous Typespublic class Customerpublic class Customer{{ public string Name;public string Name; public Address Address;public Address Address; public string Phone;public string Phone; public List<Order> Orders;public List<Order> Orders; … …}}
public class Contactpublic class Contact{{ public string Name;public string Name; public string Phone;public string Phone;}}
Customer c = GetCustomer(…);Customer c = GetCustomer(…);Contact x = Contact x = new Contact { Name = c.Name, Phone = new Contact { Name = c.Name, Phone = c.Phone }c.Phone };;
Customer c = GetCustomer(…);Customer c = GetCustomer(…);var x = var x = new { c.Name, c.Phone }new { c.Name, c.Phone };;
Customer c = GetCustomer(…);Customer c = GetCustomer(…);var x = var x = new { Name = c.Name, Phone = c.Phone }new { Name = c.Name, Phone = c.Phone };;
class ???class ???{{ public string public string Name;Name; public string public string Phone;Phone;}}
Projection style Projection style initializerinitializer
18
var contacts =var contacts = from c in customersfrom c in customers where c.State == "WA"where c.State == "WA" select new { c.Name, c.Phone };select new { c.Name, c.Phone };
Anonymous TypesAnonymous Types
var contacts =var contacts = customers.customers. .Where(c => c.State == "WA“).Where(c => c.State == "WA“) .Select(c => new { c.Name, .Select(c => new { c.Name, c.Phone });c.Phone });
class ???class ???{{ public string public string Name;Name; public string public string Phone;Phone;}}
IEnumerable<???IEnumerable<???>>
foreach (var c in contacts) {foreach (var c in contacts) { Console.WriteLine(c.Name);Console.WriteLine(c.Name); Console.WriteLine(c.Phone);Console.WriteLine(c.Phone);}}
??????
19
Query ExpressionsQuery Expressions
Language integrated query syntaxLanguage integrated query syntax
fromfrom idid inin sourcesource{ { fromfrom idid inin sourcesource | | wherewhere conditioncondition } }[ [ orderbyorderby orderingordering, , orderingordering, … ], … ]selectselect exprexpr | | groupgroup exprexpr byby keykey[ [ intointo idid queryquery ] ]
Starts with Starts with fromfrom Zero or more Zero or more
fromfrom or or wherewhere
Optional Optional orderbyorderby
Ends with Ends with selectselect or or groupgroup bybyOptional Optional intointo
continuationcontinuation
20
from c in customersfrom c in customerswhere c.State == "WA"where c.State == "WA"select new { c.Name, c.Phone };select new { c.Name, c.Phone };
customerscustomers.Where(c => c.State == "WA").Where(c => c.State == "WA").Select(c => new { c.Name, c.Phone });.Select(c => new { c.Name, c.Phone });
Query ExpressionsQuery Expressions
Queries translate to method Queries translate to method invocationsinvocations
Where, Select, SelectMany, OrderBy, Where, Select, SelectMany, OrderBy, GroupByGroupBy
21
Expression TreesExpression Trees
public class Northwind: DataContextpublic class Northwind: DataContext{{ public Table<Customer> public Table<Customer> Customers;Customers; public Table<Order> Orders;public Table<Order> Orders; … …}} Northwind db = new Northwind(…);Northwind db = new Northwind(…);
var query = from c in db.Customers where c.State == var query = from c in db.Customers where c.State == "WA" select c;"WA" select c;
Northwind db = new Northwind(…);Northwind db = new Northwind(…);var query = db.Customers.Where(c => c.State var query = db.Customers.Where(c => c.State == "WA");== "WA");
How does this How does this get remoted?get remoted?
public class Table<T>: IEnumerable<T>public class Table<T>: IEnumerable<T>{{ public Table<T> Where(Expression<Func<T, bool>> public Table<T> Where(Expression<Func<T, bool>> predicate);predicate); … …}}
Method asks Method asks for expression for expression
treetree
System.ExpressionSystem.Expressions.s.
Expression<T>Expression<T>
22
Expression TreesExpression Trees
Code as DataCode as Data
Func<Customer, bool> test = c => c.State Func<Customer, bool> test = c => c.State == "WA";== "WA";
Expression<Func<Customer, bool>> test = c => c.State Expression<Func<Customer, bool>> test = c => c.State == "WA";== "WA";
ParameterExpression c =ParameterExpression c = Expression.Parameter(typeof(Customer), "c");Expression.Parameter(typeof(Customer), "c");Expression expr =Expression expr = Expression.EQ(Expression.EQ( Expression.Property(c, Expression.Property(c, typeof(Customer).GetProperty("State")),typeof(Customer).GetProperty("State")), Expression.Constant("WA")Expression.Constant("WA") ););Expression<Func<Customer, bool>> test =Expression<Func<Customer, bool>> test = Expression.Lambda<Func<Customer, bool>>(expr, c);Expression.Lambda<Func<Customer, bool>>(expr, c);
23
LINQ Tech PreviewLINQ Tech Preview
24
C# 3.0 Language C# 3.0 Language InnovationsInnovations
Lambda expressionsLambda expressions
Extension methodsExtension methods
Local variable type inferenceLocal variable type inference
Object initializersObject initializers
Anonymous typesAnonymous types
Query expressionsQuery expressions
Expression treesExpression trees
var x = 5;var x = 5;
static void Dump(this static void Dump(this object o);object o);
c => c => c.Namec.Name
new Point { x = 1, y new Point { x = 1, y = 2 }= 2 }
new { c.Name, new { c.Name, c.Phone }c.Phone }
from … where … from … where … selectselect
Expression<TExpression<T>>
25
More InformationMore InformationWednesdayWednesday ThursdayThursday FridayFriday
TLN306TLN306 - LINQ Overview - LINQ Overview1:45 PM - 3:00 PM 1:45 PM - 3:00 PM
Halls C & DHalls C & D
TLN308TLN308 - VB 9.0 - VB 9.0 10:00 AM - 11:15 AM 10:00 AM - 11:15 AM
Room 411Room 411
DAT323 (R)DAT323 (R) - DLinq for - DLinq for SQLSQL
8:30 AM - 9:45 AM 8:30 AM - 9:45 AM Room 408 ABRoom 408 AB
TLN307TLN307 - C# 3.0 - C# 3.03:15 PM - 4:30 PM 3:15 PM - 4:30 PM
Halls C & DHalls C & D
TLN307 (R)TLN307 (R) - C# 3.0 - C# 3.02:15 PM - 3:30 PM 2:15 PM - 3:30 PM
Room 402 ABRoom 402 AB
DAT324DAT324 - XLinq - XLinq10:30 AM -11:45 AM 10:30 AM -11:45 AM
Room 408 ABRoom 408 AB
DAT323DAT323 - DLinq for SQL - DLinq for SQL2:15 PM - 3:30 PM 2:15 PM - 3:30 PM
Room 152/153 (Hall F)Room 152/153 (Hall F)
PNL11PNL11 - LINQ Panel - LINQ Panel1:00 PM - 2:30 PM 1:00 PM - 2:30 PM
Room 152/153 (Hall F)Room 152/153 (Hall F)
DAT312DAT312 - DLinq for - DLinq for WinFSWinFS
5:00 PM – 6:15 PM 5:00 PM – 6:15 PM Room 515 ABRoom 515 AB
Ask the ExpertsAsk the Experts 6:30 PM - 9:00 PM 6:30 PM - 9:00 PM
Main HallMain Hallhttp://msdn.microsoft.com/netframework/future/linq/http://msdn.microsoft.com/netframework/future/linq/
© 2005 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.