Visual Studio Codename „Orcas”, LINQ Janusz Nowak
Plan prezentacji Nowe rodzaje projektów i zmiany w VS C# 3.0 LINQ ( ang. Language INtegrated Query pol. Zintegrowany język zapytań) Co my mamy z tego? Źródła
Nowe rodzaje projektów i zmiany w VS Test Project Outlook Add-in Możliwość pisania rozszerzeń do pakietu Office Analizator kodu Śledzenie zmiennych Stos wywołań
C# 3.0 Wnioskowanie typu zmiennych lokalnych Metody rozszerzające Lambda wyrażenia Inicjatory obiektów i kolekcji Typy anonimowe Tablice z wnioskowanym typem Wyrażenia z zapytaniami Drzewa wyrażeń
C# Wnioskowanie typu zmiennych lokalnych var i = 5; var s = "Hello"; var d = 1.0; var numbers = new int[] {1, 2, 3}; var orders = new Dictionary<int,Order>(); Oznacza to samo co int i = 5; string s = "Hello"; double d = 1.0; int[] numbers = new int[] {1, 2, 3}; Dictionary<int,Order> orders = new Dictionary<int,Order>();
C# Wnioskowanie typu zmiennych lokalnych Deklaracja musi zawierać inicjator W czasie kompilacji typ wyrażenia inicjalizującego !=null Inicjator nie może być obiektem ani kolekcją, ale może być wyrażeniem, które zawiera inicjalizacje obiektu lub kolekcji Jeśli deklaracja składa się z wielu deklaracji to inicjatory muszą mieć ten sam typ w czasie kompilacji. Błędne przykłady: var x; //brak inicjacji var y = {1, 2, 3}; //inicjalizacja przez kolekcje var z = null; //typ null nie dozwolony
C# Metody rozszerzające Pozwalają na rozszerzenie istniejących typów o nowe metody Metody rozszerzające są deklarowane przez słowo „this” w pierwszym parametrze metody (this string s) Metody rozszerzające możemy deklarować tylko w statycznych klasach Importujemy metody rozszerzające przez „using” nazwa_namespace; (using Acme.Utilities;) Możemy wołać nowe metod używając składni instancyjnych metod
C# Metody rozszerzające namespace Acme.Utilities { public static class Extensions { public static int ToInt32(this string s) { return Int32.Parse(s); } } Użycie metod rozszerzających using Acme.Utilities; string s = "1234"; int i= s.ToInt32();// To samo co Extensions.ToInt32(s)
C# Lambda wyrażenia Lambda wyrażenia jest to nowy sposób pisania anonimowych metod z wnioskowaniem typów oraz możliwością przekształcenia do typów delegowanych i drzewa wyrażeń. Przykład: listOfFoo.Where(delegate(Foo x) { return x.size>10;}) możemy zapisać listOfFoo.Where(x => x.size>10);
C# Lambda wyrażenia Przykłady: x => x + 1 // domniemany typ, treść będąca wyrażeniem x => { return x + 1; } // typ wywnioskowany, deklaracja (int x) => x + 1 // jawny typ, treść będąca wyrażeniem (int x) => { return x + 1; }// jawny typ, deklaracja (x, y) => x * y // kilka parametrów () => Console.WriteLine() // bez parametrów
C# Lambda wyrażenia Co dają nam lambda wyrażenia: Anonimowe metody wymagają podania typu, lambda wyrażenia nie. Wyrażenie lambda może być deklaracją lub wyrażeniem zaś metoda anonimowa tylko deklaracją Wyrażenie lambda może zostać uznane za drzewo wyrażenia.
C# Inicjatory obiektów i kolekcji Pozwalają nam na łatwe konstruowanie i inicjalizowanie obiektów. Oszczędność kodu.
C# Inicjatory obiektów public class Punkt { int x, y; public int X { get { return x; } set { x = value; } } public int Y { get { return y; } set { y = value; } } } Możemy stworzyć obiekt tej klasy w ten sposób: var a = new Punkt { X = 0, Y = 1 }; co ma taki sam efekt co: var a = new Punkt(); a.X = 0; a.Y = 1;
C# Inicjatory public class Prostokąt// składająca się z 2punktów { Punkt p1, p2; public Punkt P1 { get { return p1; } set { p1 = value; } } public Punkt P2 { get { return p2; } set { p2 = value; } } } Obiekt tej klasy możemy stworzyć przez: var r = new Prostokąt { P1 = new Punkt { X = 0, Y = 1 }, P2 = new Punkt { X = 2, Y = 3 } }; co ma ten sam efekt co var r = new Prostokąt(); var __p1 = new Punkt(); __p1.X = 0; __p1.Y = 1; r.P1 = __p1; var __p2 = new Punkt(); __p2.X = 2; __p2.Y = 3; r.P2 = __p2; Zmienne __p1 i __p2 są tymczasowe, niedostępne i niewidoczne
C# Inicjatory obiektów Natomiast gdy konstruktor Prostokąta tworzy dwa obiekty Punkt public class Prostokąt { Punkt p1 = new Punkt(); Punkt p2 = new Punkt(); public Punkt P1 { get { return p1; } } public Punkt P2 { get { return p2; } } } Obiekt tej klasy możemy stworzyć przez var r = new Prostokąt { P1 = { X = 0, Y = 1 }, P2 = { X = 2, Y = 3 } }; lub var r = new Prostokąt(); r.P1.X = 0; r.P1.Y = 1; r.P2.X = 2; r.P2.Y = 3;
C# Inicjatory kolekcji public class Kontakt { string name; List<string> pNumbers = new List<string>(); public string Name { get { return name; } set { name = value; } } public List<string> PNumbers { get { return pNumbers; } } } List<Kontakt> możemy stworzyć i zainicjować w poniższy sposób: var contacts = new List<Kontakt> { new Contact {Name = "Chris Smith", PNumbers = { "206-555-0101", "425-882-8080" }}, new Contact {Name = "Bob Harris", PNumbers = { "650-555-0199" } } };
C# Inicjatory kolekcji Ma to ten sam efekt co var contacts = new List<Kontakt>(); var __c1 = new Contact(); __c1.Name = "Chris Smith"; __c1.PNumbers.Add("206-555-0101"); __c1.PNumbers.Add("425-882-8080"); contacts.Add(__c1); var __c2 = new Contact(); __c2.Name = "Bob Harris"; __c2.PNumbers.Add("650-555-0199"); contacts.Add(__c2);
C# Typy anonimowe Inicjalizator != null. Nazwa anonimowego typu jest automatycznie generowana przez kompilator w czasie kompilacji i nie możemy się do niej odwoływać w programie. Jeśli w programie podamy dwa inicjatory anonimowego obiektu, które mają takie same nazwy parametrów tego samego typu w tej samej kolejności, to będą to instancje tego samego typu. Przykład: var p1 = new { Name = "Lawnmower", Price = 495.00 }; var p2 = new { Name = "Shovel", Price = 26.95 }; p1 = p2; //OK ponieważ ten sam anonimowy typ
C# Tablice z wnioskowanym typem Domniemany typ tablic, sposób tworzenia i inicjalizacji tablic, których typ jest wnioskowany po elementach inicjalizujących. Inicjator musi zawierać jeden typ, dla którego wszystkie elementy z zbioru dadzą się przekonwertować i nie jest to null. Przykłady var a = new[] { 1, 10, 100, 1000 }; // int[] var b = new[] { 1, 1.5, 2, 2.5 }; // double[] var c = new[] { "hello", null, "world” }; // string[] var d = new[] { 1, "one", 2, "two" }; // Error
C# Tablice z wnioskowanym typem Wnioskowanie typu tablic możemy połączyć z anonimowo inicjacja obiektów, żeby stworzyć anonimowo strukturę danych. np..: var contacts = new[] { new { Name = "Chris Smith", PhoneNumbers = new[] { "206-555-0101", "425-882-8080" }}, new { Name = "Bob Harris", PhoneNumbers = new[] { "650-555-0199" } } };
C# Wyrażenia z zapytaniami Możliwość użycia zapytań w stylu SQL lub XQuery dla kolekcji, tablic w C#. Przykłady zapytań:
C# Wyrażenia z zapytaniami Where from c in customers where c.City == "London" select c Będzie przetłumaczone na customers. Where(c => c.City == "London") Select from c in customers where c.City == "London" select c.Name Group from c in customers group c.Name by c.Country
C# Wyrażenia z zapytaniami Orderby from c in customers orderby c.Name select new { c.Name, c.Phone }//anonimowy typ Złożone zapytania 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 }
C# Drzewa wyrażeń Drzewa wyrażeń pozwalają na to, żeby wyrażenia lambda były reprezentowane jako dane zamiast kodu (delegat). Func<int,int> f = x => x + 1; // Code Expression<Func<int,int>> e = x => x + 1;// Data delegat f odwołuje się do metody, która wylicza x + 1, a drzewo wyrażenia opisuje wyrażenie x + 1.
LINQ LINQ dla C#, VB oraz innych języków w przyszłości F# … Odmiany: Linq - Obiekty film DLinq - Bazy danych film XLinq – Xml film
Co my mamy z tego? Łatwiejsze połączenie dwóch światów baz danych i obiektów. Moc XPath i XQuery dla XML w C# 3.0 . Nowe możliwości operowania na obiektach. Testowanie.
Źródła http://msdn.microsoft.com/data/ref/linq/ http://channel9.msdn.com/showpost.aspx?postid=114680
KONIEC