Programming with C# 3.0
» Andrea Dottor – Microsoft MVP ASP/ASP.NET
Perchè questa sessione
» Perchè una sessione su C# 3.0?
05/06/2009
www.xedotnet.org
2
Agenda
» Agenda:
•
•
•
•
•
•
•
•
•
•
•
•
Auto-Implemented Properties
Partial Method Definitions
Extension Methods
Implicitly Typed Local Variables and Arrays
Object Initializers
Collection Initializers
Anonymous Method
Lambda Expressions
Anonymous Types
Linq
Query Expression
Expression tree
05/06/2009
www.xedotnet.org
3
Auto-Implemented Properties
» Auto-Implemented Properties
class Car
{
// Automatic property syntax.
public string PetName { get; set; }
}
• Permettono di specificare una proprietà senza
doverne specificare il field privato
• Velocizza il processo di creazione di proprietà
all’interno delle classi
• E’ accessibile attraverso lo snippet ‘prop’ di Visual
Studio 2008
05/06/2009
www.xedotnet.org
4
Auto-Implemented Properties
» Auto-Implemented Properties
• Il membro privato viene generato a compile-time
• Per vedere il nome del field privato generato, è
necessario utilizzare ildasm.exe o Reflector.exe
(tools che permettono di decompilare il codice MSIL)
• Non è possibile utilizzarle per specificare proprietà in
read-only o write-only
// Read-only property? Error!
public int MyReadOnlyProp { get; }
// Write only property? Error!
public int MyWriteOnlyProp { set; }
05/06/2009
www.xedotnet.org
5
Auto-Implemented Properties
» Auto-Implemented Properties
• E’ possibile limitare l’accesso al get o al set di una
proprietà, specificandone la visibilità
public string PetName { get; protected set; }
• Non è possibile specificare un valore di default a
causa del membro privato che non è presente
• Nel costruttore della classe si può intervenire
impostando il valore di default
05/06/2009
www.xedotnet.org
6
Partial Method Definitions
» Partial Method Definitions
• E’ stata aggiunta la possibilità di definire un metodo
come “partial”
• Permette di definire un metodo in una classe, e
poterlo implementare in un’altra classe
partial class CarLocator
{
public bool CarAvailableInZipCode(string zipCode)
{
VerifyDuplicates(zipCode);
return true;
}
partial void VerifyDuplicates(string make);
}
05/06/2009
www.xedotnet.org
7
Partial Method Definitions
» Partial Method Definitions
• I metodi dichiarati come “partial” hanno delle
limitazioni:
•
•
•
•
Devono essere definiti all’interno di una partial class
Devono sempre ritornare void
Possono avere argomenti, ma non con clausula “out”
Sono sempre implicitamente privati
• Se un metodo partial non viene implementato,
questo non compare nel codice compilato
(nemmeno la chiamata del metodo)
05/06/2009
www.xedotnet.org
8
DEMO
05/06/2009
www.xedotnet.org
9
Extension Methods
» Extension Methods
• Permettono di aggiungere metodi a tipi “compilati”
(classi, strutture, implementazioni di interfacce)
• Aggiungono funzionalità alle classi senza doverle
modificare o ricompilare
• Grosso vantaggio in quanto permettono di aggiungere
metodi a classi di qui non si possiede il codice
05/06/2009
www.xedotnet.org
10
Extension Methods
» Extension Methods
• Vincoli:
• Devono essere in una classe statica
• Come primo argomento devono avere la clausola “this”
• Devono essere chiamati da un specifico tipo di instanza (in
memoria) oppure tramite la classe statica
static class MyExtensions
{
public static void DisplayDefiningAssembly(this object obj)
{
Console.WriteLine("{0} lives here:{1}",
obj.GetType().Name,
Assembly.GetAssembly(obj.GetType())); }
}
05/06/2009
www.xedotnet.org
11
DEMO
05/06/2009
www.xedotnet.org
12
Implicitly Typed Local Variables and Arrays
» Implicitly Typed Local Variables and Arrays
• E’ possibile dichiarare le variabili in modo implicito,
utilizzando la parola chiave “var”
• “var” non è “variant”
• Sarà il compilatore a capire il tipo corretto da
utilizzare
• Visual Studio è in grado di indicarci l’esatto tipo della
variabile
var i = 5;
var s = “ciao”;
var numeri = new int[] {1, 2, 3};
var conn = new OleDbConnection();
05/06/2009
www.xedotnet.org
13
Implicitly Typed Local Variables and Arrays
» Implicitly Typed Local Variables and Arrays
• E’ possibile utilizzare la keywork “var” anche
all’interno di cicli for e foreach
var evenNumbers = new int[] { 2, 4, 6, 8 };
// Use "var" in a standard foreach loop.
foreach (var item in evenNumbers)
{
Console.WriteLine("Item value: {0}", item);
}
…
// Use a strongly typed System.Int32 to iterate over contents.
foreach (int item in evenNumbers)
{
Console.WriteLine("Item value: {0}", item);
}
05/06/2009
www.xedotnet.org
14
Implicitly Typed Local Variables and Arrays
» Implicitly Typed Local Variables and Arrays
• Esistono però delle limitazioni:
• Può essere utilizzata solamente per variabili locali
• Non può essere utilizzata per definifire valori di ritorno,
parametri o proprietà
• Nella dichiarazione deve obbligatoriamente essere fatto
anche l’assegnamento
• Nella dichiarazione non si può assegnare valore “null”
• Non può essere definita come nullable
05/06/2009
www.xedotnet.org
15
Object Initializers
» Object Initializers
• Permette di impostare le proprietà di un oggetto in
fase di creazione di una classe, senza richiamare il
costruttore in modo esplicito
// Make a Point by setting each property manually...
Point firstPoint = new Point();
firstPoint.X = 10;
firstPoint.Y = 10;
// ...or make a Point via a custom constructor...
Point anotherPoint = new Point(20, 20);
// ...or make some Point types using the new object init syntax.
var yetAnotherPoint = new Point { X = 30, Y = 30 };
Point finalPoint = new Point { X = 30, Y = 30 };
05/06/2009
www.xedotnet.org
16
Object Initializers
» Object Initializers
• E’ possibile chiamare esplicitamente il costruttore di
default
// Here, the default constructor is called implicitly.
Point finalPoint = new Point { X = 30, Y = 30 };
• Oppure esplicitamente
// Here, the default constructor is called explicitly.
Point finalPoint = new Point() { X = 30, Y = 30 };
• Oppure chiamare un costruttore custom prima di
inizializzare l’oggetto
// Calling a custom constructor.
Point pt = new Point(10, 16) { X = 100, Y = 100 };
05/06/2009
www.xedotnet.org
17
Collection Initializers
» Collection Initializers
• Utilizzando la stessa sintassi utilizzata per
inizializzare gli array, è possibile inizializzare anche
collezioni e liste
// Init a standard array.
int[] myArrayOfInts = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// Init a generic List<> of ints.
List<int> myGenericList = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// Init an ArrayList with numerical data.
ArrayList myList = new ArrayList { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
05/06/2009
www.xedotnet.org
18
Collection Initializers
» Collection Initializers
• E’ possibile combinare le Collection Initializers con
Object Initializers per inizializzare oggetti complessi
List<Rectangle> myListOfRects = new List<Rectangle>
{
new Rectangle {
TopLeft = new Point { X = 10, Y = 10 },
BottomRight = new Point { X = 200, Y = 200}},
new Rectangle {
TopLeft = new Point { X = 2, Y = 2 },
BottomRight = new Point { X = 100, Y = 100}},
new Rectangle {
TopLeft = new Point { X = 5, Y = 5 },
BottomRight = new Point { X = 90, Y = 75}}
};
05/06/2009
www.xedotnet.org
19
DEMO
05/06/2009
www.xedotnet.org
20
PAUSA
05/06/2009
www.xedotnet.org
21
delegate
» ...torniamo indietro e vediamo cosa sono
I DELEGATE
• La parola riservata delegate serve a definire un tipo
in grado di puntare a un metodo e gestire
indirettamente la sua invocazione.
• Possiamo vedere un delegate come un "puntatore a
funzione“
• Offrono la possibilità di chiamare un metodo (anche)
in modo asincrono tramite BeginInvoke e EndInvoke
• Vengono utilizzati principalmente per la gestione
degli eventi
05/06/2009
www.xedotnet.org
22
delegate
» ...torniamo indietro e vediamo cosa sono
I DELEGATE
public delegate object MioDelegate(int numero);
public class ClasseEsempio
{
public object metodoEsempio(int numero)
{...}
}
public static void Main()
{
ClasseEsempio classe = new ClasseEsempio();
MioDelegate dele = new MioDelegate(classe.metodoEsempio);
object risultato = dele(110);
}
05/06/2009
www.xedotnet.org
23
Anonymous Types
» Anonymous Method
• Offrono la possibilità di specificare un blocco di
codice ad un metodo (“inline”) tramite delegate
static void Main(string[] args)
{
SomeType t = new SomeType();
t.SomeEvent += delegate (optionallySpecifiedDelegateArgs)
{ /* statements */ };
}
button1.Click += delegate(object sender, EventArgs e) {
Console.WriteLine("Message : {0}", textBox1.Text);
};
05/06/2009
www.xedotnet.org
24
Lambda Expressions
» Lambda Expressions
• Permettono di gestire gli eventi “inline”, associando
direttamente un blocco di codice
• Permettono di creare un metodo “stand-alone”
all’interno del codice (utilizzando gli anonymous
methods)
• Sono un’ulteriore semplificazione rispetto l’uso dei
delegate
• Il compilatore converte una lambda expression in un
standard anonymous method che fa uso di
Predicate<T>
05/06/2009
www.xedotnet.org
25
Lambda Expressions
» Lambda Expressions
// Lambda expression...
List<int> evenNumbers = list.FindAll(i => (i % 2) == 0);
// Il compilatore la traduce in questo anonymous method.
List<int> evenNumbers = list.FindAll(delegate (int i) { return (i % 2) == 0; });
• Una lambda expression è composta da una serie di
parametri seguiti dai caratteri =>, seguiti a sua volta
dal codice che processerà gli argomenti.
ArgumentsToProcess => StatementsToProcessThem
05/06/2009
www.xedotnet.org
26
Lambda Expressions
» Lambda Expressions
• I parametri possono essere dichiarati esplicitamente.
List<int> evenNumbers = list.FindAll((int i) => (i % 2) == 0);
• Le lambda expression possono contenere più linee di
codice
List<int> evenNumbers = list.FindAll((i) =>
{
Console.WriteLine("value of i is currently: {0}", i);
bool isEven = ((i % 2) == 0);
return isEven;
});
05/06/2009
www.xedotnet.org
27
Lambda Expressions
» Lambda Expressions
• Possono avere più argomenti
m.SetMathHandler((msg, result) =>
{Console.WriteLine("Message: {0}, Result: {1}", msg, result);});
• …ma anche nessuno
VerySimpleDelegate d = new VerySimpleDelegate( () => {return "Enjoy your string!";} );
Console.WriteLine(d.Invoke());
05/06/2009
www.xedotnet.org
28
DEMO
05/06/2009
www.xedotnet.org
29
Anonymous Types
» Anonymous Types
• Permettono di creare ed inizializzare un nuova classe.
• E’ possibile utilizzarla grazie alla keyword var
(Implicitly Typed)
• La classe verrà generata automaticamente in fase di
compilazione, e deriverà da System.Object
• La classe può essere utilizzata solo all’interno
dell’applicazione (viene generato come internal
sealed)
var myCar = new { Color = "Bright Pink", Make = "Opel", CurrentSpeed = 55 };
05/06/2009
www.xedotnet.org
30
Linq
» Linq
• LINQ è il termine utilizzato per definire questo un
tipo di approccio per l’accesso ai dati.
• Fornisce delle API che permetteno di eseguire delle
query expression (sia in lettura che scrittura) verso
classi che implementano IEnumerable<T>, database
relazionali, DataSets, o documenti XML. (etc etc ...)
05/06/2009
www.xedotnet.org
31
Linq
» Linq
• LINQ è una tecnologia estensibile, in quanto può
essere implementata per accedere a diverse sorgenti
dati
• Esistono diversi tipi di implementazioni:
• LINQ to Objects è LINQ verso classi che implementano
IEnumerable<T>
• LINQ to SQL è LINQ verso database relazionali (SQL Server)
• LINQ to DataSet è un subset di LINQ to SQL
• LINQ to XML è LINQ verso documenti XML
05/06/2009
www.xedotnet.org
32
Linq
Assembly
Descrizione
System.Core.dll
Defines the types that represent the core
LINQ API. This is the one assembly you must
have access to.
System.Data.Linq.dll
Provides functionality for using LINQ with
relational databases (LINQ to SQL).
System.Data.DataSetExtensions.dll Defines a handful of types to integrate
ADO.NET types into the LINQ programming
paradigm (LINQ to DataSet).
System.Xml.Linq.dll
Provides functionality for using LINQ with
XML document data (LINQ to XML).
• Qualsiasi implementazione di LINQ si voglia
utilizzare, si dovrà importare il namespace
System.Linq (contenuto in System.Core.dll)
05/06/2009
www.xedotnet.org
33
Query Expression
» Query Expression
• Definiscono delle query verso una sorgente dati, utilizzando
dei query operators (es: from, in, where, orderby, e select)
• Le LINQ query expression sono strongly typed. Il compilatore
verificherà la corretta sintassi delle query.
string[] currentVideoGames = {"Morrowind", "BioShock",
"Half Life 2: Episode 1", "The Darkness",
"Daxter", "System Shock 2"};
IEnumerable<string> subset = from g in currentVideoGames
where g.Length > 6 orderby g select g;
• Il tipo di dati ritornato è del tipo IEnumerable<T>
05/06/2009
www.xedotnet.org
34
Query Expression
» Query Expression
• Una query expression viene useguita quando viene valutata
int[] numbers = { 10, 20, 30, 40, 1, 2, 3, 8 };
var subset = from i in numbers where i < 10 select i;
// LINQ statement evaluated here!
foreach (var i in subset)
Console.WriteLine("{0} < 10", i);
// Change some data in the array.
numbers[0] = 4;
// Evaluate again.
foreach (var j in subset)
Console.WriteLine("{0} < 10", j);
05/06/2009
www.xedotnet.org
35
Query Expression
» Query Expression
• Per avere una esecuzione immediata della query, si
possono utilizzare i metodi ToArray<T>(),
ToDictionary<TSource,TKey>(), e ToList<T>()
int[] numbers = { 10, 20, 30, 40, 1, 2, 3, 8 };
// Get data RIGHT NOW as int[].
int[] subsetAsIntArray = (from i in numbers where i < 10 select i).ToArray<int>();
// Get data RIGHT NOW as List<int>.
List<int> subsetAsListOfInts = (from i in numbers where i < 10 select i).ToList<int>();
05/06/2009
www.xedotnet.org
36
Expression tree
» Expression tree
• Forniscono una rappresentazione ad oggetti di una
lambda expression.
• Sono compilati, strong-typed, provider independent
e serializzabili.
• Sono Immutabili, e quindi per modificarne una sua
parte, si deve creare un nuovo Expression Tree
05/06/2009
www.xedotnet.org
37
Expression tree
» Expression tree
05/06/2009
www.xedotnet.org
38
Expression tree
» Expression tree
• Visione di una lambda expression come Expression Tree
// Create an expression tree.
Expression<Func<int, bool>> exprTree = num => num < 5;
// Decompose the expression tree.
ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
BinaryExpression operation = (BinaryExpression)exprTree.Body;
ParameterExpression left = (ParameterExpression)operation.Left;
ConstantExpression right = (ConstantExpression)operation.Right;
Console.WriteLine("Decomposed expression: {0} => {1} {2} {3}",
param.Name, left.Name, operation.NodeType, right.Value);
/* This code produces the following output:
Decomposed expression: num => num LessThan 5
*/
05/06/2009
www.xedotnet.org
39
Expression tree
» Expression tree
• Creazione di un Expression Tree
// Create the parameter "x" in x + 1
ParameterExpression p0 = Expression.Parameter(typeof(int), "x");
// Create the constant 1 in x + 1
ConstantExpression c0 = Expression.Constant(1);
// Build the addition expression x + 1 using the above
// Note it will really look like Add(x,1)
BinaryExpression expression = Expression.Add(p0, c0);
// Create the Lamda Expression x => Add(x,1)
var lambdaExpression = Expression.Lambda<Func<int,int>> (expression, new ParameterExpression[] { p0 });
// Let's compile it so we can use it
var theDelegate = lambdaExpression.Compile();
// Execute... 6 + 1 = 7
var seven = theDelegate.Invoke(6);
05/06/2009
www.xedotnet.org
40
DEMO
05/06/2009
www.xedotnet.org
41
Extension Methods
» Cosa ci sarà di nuovo su C# 4.0?
• Dynamic Typed Objects
• Dichiarazione di oggetti di tipo dinamico, che possono cambiare
il loro tipo in fase di runtime.
dynamic myVar = "Andrea";
myVar = 14;
• Optional and Named Parameters
• Parametri opzionali nei metodi.
MyMethod(Name: "Andrea");
MyMethod(Name: "Andrea", Id: 1);
• Improved COM Interoperability
• Covariance – Contravariance
• Permette di trattare gli oggetti come il tipo da cui deriva
public class Second : First
List<Second> xsecond = new List<Second>();
List<First> xfirst = xsecond;
05/06/2009
www.xedotnet.org
42
Sponsor
In collaborazione con
Links
Andrea Dottor
blog: blog.dottor.net
email: [email protected]
live messenger: [email protected]
community: http://www.xedotnet.org
05/06/2009
www.xedotnet.org
44
Scarica

query expression