C# 3.0: C# 3.0 Harjeet Singh
Version 3: Version 3 From PDC 2005
preview compiler available
LINQ: language-integrated query
High level points:
adds native query functionality to C#
adds better functional programming
Several changes required to make this work
implicitly typed variables
extension methods
Implicitly typed variables: Implicitly typed variables var i = 5; var s = "Hello"; var d = 1.0; var orders = new Dictionary<int,Order>();
Type of the variable induced from expression
must include initializer
can’t be null. Why not?
What happens if “var” is a class in scope?
Works in for loops
Extension methods: Extension methods Can add methods to other classes
any methods (although look static)
only from static classes
When import a namespace that has extensions, then added to classes
once imported, called as usual
Local methods take precedence
first local for normal method, then extension
Extension methods: Extension methods public static class Extensions
{
public static int ToInt32(this string s) {
return Int32.Parse(s); }
public static T[] Slice<T>(this T[] source, int index, int count) { if (index < 0 || count < 0 || source.Length – index < count) throw new ArgumentException(); T[] result = new T[count]; Array.Copy(source, index, result, 0, count); return result; }
}
Extension methods: Extension methods using N1;
namespace N1 { public static class E { public static void F(this object obj, int i) { }
public static void F(this object obj, string s) { } } }
class A { }
class B { public void F(int i) { } }
class C { public void F(object obj) { } }
Extension methods: Extension methods class X { static void Test(A a, B b, C c) { a.F(1); a.F("hello");
b.F(1); b.F("hello");
c.F(1); c.F("hello"); } }
Extension methods: Extension methods Not for properties, events, operators
currently under consideration
Equivalent to calling the static method
difference from actually extending the class?
How could we use this for Polynomials?
Disadvantages?
implicitness
security
Lambda expressions: Lambda expressions Generalized function syntax
x . x + 1
in C# 3.0, have x => x + 1
From anonymous delegate syntax:
delegate(int x) { return x + 1;}
Can have implicitly typed variables
Can have more than one variable
Can have expression or statement body
NB: no statement bodies in preview compiler
Lambda expressions: Lambda expressions Can be converted to delegate type
if parameters and body match
delegate R Func<A,R>(A arg); Func<int,int> f1 = x => x + 1; Func<int,double> f2 = x => x + 1; Func<double,int> f3 = x => x + 1;
Participate in type inference
If expression body, get expression trees
Lambda expressions: Lambda expressions Type inference public static IEnumerable<S> Select<T,S>( this IEnumerable<T> source, Func<T,S> selector) { foreach (T element in source) yield return selector(element); }
If call Select(customers, c => c.Name);
T, S mapped to appropriate types
Lambda expressions: Lambda expressions Given the code
delegate R Func<A,R>(A arg); static Z F<X,Y,Z>(X value, Func<X,Y> f1, Func<Y,Z> f2) { return f2(f1(value)); }
what happens when get the following? F("1:15:30", s => TimeSpan.Parse(s), t => t.TotalSeconds)
Intializers: Intializers Can initialize fields like attribute fields
new C(1, 2, name=“my class”);
works if public field or if property with set
can be nested (eg. Rectangle with two Points)
Collection initializers
List<int> digits = new List<int> { 0, 1};
Must implement System.Generic.ICollection<T>
Object initializers
var a = new Point { X = 0, Y = 1 };
Anonymous types: Anonymous types var x = new {p1 = 10, p2 = “name”};
x is of anonymous type
type can’t be referred to by name in program
structural type equivalence
two anonymous types can be compatible
implicitly typed arrays
var a = new[] { 1, 10, 100, 1000 };
must have consistent types
or have implicit conversions
Query expressions: Query expressions Adds querying to language
important for interaction with DB
but also with built-in data structures
leave query planning to data structure designer
Implemented using above functionality
anonymous types and variables useful
lambda expressions make it cleaner.
Query expressions: Query expressions eg. var x = from s in students where s.City == “Ithaca" select s;
defines an expression
translates to invocation of Where method on students
if select contains expression, calls Select
uses lambda expressions as parameters
we saw Select above
Other clauses: Other clauses groupby
from c in customers group c.Name by c.Country
c.GroupBy(c => c.Name, c => c.Country);
orderby from c in customers orderby c.Name select new { c.Name, c.Phone }
multiple from clauses from c in customers where c.City == "London" from o in c.Orders where o.OrderDate.Year == 2005 select new { c.Name, o.OrderID, o.Total }
Other clauses: Other clauses inner join?
can be done with multiple generators
just use a different object internally
not as efficient?
maybe need more syntax?
don’t have full spec yet, just examples
Query expression pattern: Query expression pattern As with collections:
not an interface
just need to implement the methods
necessary for backwards compatibility
methods may be implemented by extension
Methods named as above
Any class that implements pattern can be accessed via the new syntax
Sequences: Sequences A collection IEnumerable<T>
given iterator, can be viewed as a sequence
New extension operators
Take/TakeWhile
Skip/SkipWhile
Reverse
Concat
Intersect/Union/Except
Expression trees: Expression trees Data structure that represents expression
type Expression<D> if D is delegate type
eg. Expression<Func<T>> e = x => x + 1;
can be used to parse the function
Spec not currently available
Idea
take an expression tree and convert to SQL
Database Integration: Database Integration Final step
don’t think about the database types as separate
allow databases to back classes!
How would you do this in C#?
Queries are now in the language
eg. var x = from s in sources where s.fileName == “Polynomial.cs” select s;
DLinq Attributes: DLinq Attributes [Table(Name="DVDTable")] public class DVD { [Column(Id = true)] public string Title;
[Column] public string Rating; }
Connections Revisited: Connections Revisited public class MyDVDs : DataContext { public Table<DVD> DVDs;
public MyDVDs(string connection) : base(connection) {} }
creates the connection to a database
MyDVDs db = new MyDVDs(“dvd.mdf”); var x = from d in db.DVDs where d.Rating == “G” select d;
DLinq Query Expressions: DLinq Query Expressions var x = <some query>
the query is not executed immediately
why not?
Convert to Query<DVD>
holds the actual query as an Expression tree
convert to SQL at execution time. When?
eg. when need IEnumerator for foreach
Changes: Changes db.SubmitChanges()
try to update the DB with our changes
may fail: why?
other applications may have made modifications
what should we do?
db.RejectChanges()
throw away all changes since last updated
Concurrency control
optimistic in general
Transactions: Transactions Transaction: unit of work
isolated from other units
can be made to look like happening serially
using(TransactionScope ts = new TransactionScope()) { db.SubmitChanges(); ts.Complete(); }
creates a new transaction for these updates
if transaction succeeds, all changes accepted
if transaction aborts, no object rollback
XLinq: XLinq Instant XML intro
language for defining markup
nested tags and attributes
eg <name instructor=“true”>Tom Roeder</name>
XML used as a document language
often want to extract information from XML
eg. in web search
What is the relationship to DBs?
C# XML Programming: C# XML Programming Current model
Read in XML document via various methods
everything based in XMLDocument
XLinq model
XElement
no document requirements: can be created anywhere
can be queried as in DLinq
built up functionally
XLinq Query Example: XLinq Query Example from c in contacts.Elements("contact") where (string) c.Element("address").Element("state") == "WA" orderby (string) c.Element("name") select (string) c.Element("name");
What is the difference with DLinq?
why all the casts?
how to fix?
LINQ team looking into schema support
adds metadata to XML queries
C# 3.0 Conclusions: C# 3.0 Conclusions query ability useful but many things are
adding functional programming increases the possible styles of C# programming
additions apparently not made on general principles but to support a particular narrow model of programming.
Nonetheless: try it out