Introduzione a C#
Introduzione a C#
Carlo Becchi
[email protected]
1
Introduzione a C#
C#: Strumento Principe per .net
• Primo linguaggio orientato alle
componenti della famiglia C/C++
• Tutto è DAVVERO un oggetto
• Unisce potenza, semplicità e
chiarezza di C++, Java, VB…
• Completamente nuovo, non ha
vincoli con il passato
2
Introduzione a C#
C#: Strumento Principe per .net
• Indipendente dalla piattaforma e
scalabile
• “Nato con” e “cucito addosso” al
.NET Framework
• Può essere integrato nelle pagine
web
• Completamente Type Safe
3
Introduzione a C#
C#: Strumento Principe per .net
• Standardizzato dall’ECMA
• Ideato da Anders Hejlsberg e dal
team di J++
4
Introduzione a C#
In principio fu System.Object
5
Introduzione a C#
Tutto è un oggetto
• In C# tutti i tipi reference, sono derivati
dal tipo base System.Object.
• Ogni oggetto eredita i metodi base da
System.Object
… ma proprio OGNI* tipo…
*Mediante il meccanismo di Boxing
6
Introduzione a C#
Tutto è un oggetto
using System;
class Test
{
static void Main() {
Console.WriteLine(3.ToString());
}
}
ToString restituisce una stinga che rappresenta il valore
dell’oggetto
7
Introduzione a C#
In particolare la classe System.Object offre i seguenti metodi:
Equals (public, virtual): Permette la comparazione di due oggetti per stabilire
se il loro valore è uguale.
GetHashCode (public, virtual): Permette ai tipi di restituire un integer a 32bit
con segno come codice hash per i suoi oggetti. Si solito viene utilizzato per
memorizzare oggetti in una tabella hash.
ToString (public, virtual): Permette ad un tipo di fornire in ritorno una stringa
che rappresenta il valore dell’oggetto.
GetType (public, non-virtual): Restituisce un oggetto che rappresenta il tipo
dell’oggetto.
MemberwiseClone (protected, non-virtual): Permette al tipo di costruire una
nuova istanza che è copia di se stesso.
Finalize (protected, virtual): Permette di ripulire dalla memoria gli oggetti del
tipo e rilasciare le risorse associate.
Tutto è un oggetto
8
Introduzione a C#
Tutto è un oggetto
using System;
public class MyClass
{
public static void Main()
{
object a;
a = 1;
// un esempio di boxing
Console.WriteLine(a);
Console.WriteLine(a.GetType());
Console.WriteLine(a.ToString());
Console.WriteLine();
}
}
Output
1
System.Int32
1
9
Introduzione a C#
Hello, World!
10
Introduzione a C#
Hello, World!
• Si utilizza il metodo WriteLine della
classe Console, presente nel
namespace System contenuto
nell’assembly mscorlib.dll.
• Salutiamo il mondo in C#, VB e C++
11
Introduzione a C#
Hello, World: C#
// Permette riferimenti semplificati al namespace System
using System;
// Questa classe esiste solo per ospitare la funzione entry point
dell'applicazione
class MainApp {
// Il metodo statico Main è l'entry point dell'applicazione
public static void Main() {
// Scrive il testo sulla console
Console.WriteLine("Hello World using C#!");
}
}
12
Introduzione a C#
Hello, World: VB
' Permette riferimenti semplificati al namespace System
Imports System
' Il Module ospita l'entry point dell'applicazione
Public Module modmain
' "Main" è l'entry point dell'applicazione
Sub Main()
' Scrive il testo sulla console
Console.WriteLine ("Hello World using Visual Basic!")
End Sub
End Module
13
Introduzione a C#
Hello, World: C++
// L'utilizzo dell'assemby mscorlib.dll deve essere specificato!
#using <mscorlib.dll>
// Permette riferimenti semplificati al namespace System
using namespace System;
// La global function "main" è l'entry point dell'applicazione
void main()
{
// Scrive il testo sulla console
Console::WriteLine("Hello World using Managed Extensions for
C++!");
}
14
Introduzione a C#
Sviluppo Cross Language
15
Introduzione a C#
Sviluppo Cross Language
• L’interoperabilità tra linguaggi
aderenti al CLS è immediata
• Da una classe base scritta in C++ ne
sarà derivata una in VB, dalla quale
ne sarà derivata una in IL e da C#…
16
Introduzione a C#
VCBase.cpp
#using <mscorlib.dll>
using namespace System;
public class VCBase
{
protected:
VCBase(){
Console::WriteLine(" Executing the VCBase::VCBase() constructor");
}
public:
virtual void Method() = 0;
void MethodThatThrows(){
throw(new OutOfMemoryException("We are out of some resource!"));
}
};
17
Introduzione a C#
VBDerived.vb
Option Explicit On
Option Strict On
Imports System
Public Class VBDerived
Inherits VCBase
Public Sub New()
Console.WriteLine("
Executing the VBDerived.New() constructor")
End Sub
Overrides Public Sub Method
Console.WriteLine(" Executing the VBDerived.Method() virtual method")
End Sub
End Class
18
Introduzione a C#
.module extern VBDerived.netmodule
ILDerived.il
.class public auto ansi ILDerived
extends [.module VBDerived.netmodule]VBDerived
{
.method public specialname rtspecialname
instance void .ctor() il managed
{
.maxstack 1
.locals init (class System.Object[] V_0)
IL_0000: ldarg.0
IL_0001: call
instance void [.module VBDerived.netmodule]VBDerived::.ctor()
IL_0006: ldstr
"
Executing the ILDerived::ctor() constructor"
IL_000b: call
void [mscorlib]System.Console::WriteLine(class System.String)
IL_0010: ret
}
.method public virtual instance void Method() il managed
{
.maxstack 1
.locals init (class System.Object[] V_0)
IL_0000: ldstr
" Executing the ILDerived::Method() virtual method"
IL_0005: call
void [mscorlib]System.Console::WriteLine(class System.String)
IL_000a: ret
}
}
19
Introduzione a C#
CSDerived.cs
using System;
public class CSDerived:ILDerived{
public CSDerived(){
Console.WriteLine("Executing the CSDerived.CSDerived() constructor");
}
override public void Method(){
Console.WriteLine(" Executing the CSDerived.Method() virtual method");
}
}
20
Introduzione a C#
class App{
public static void Main(){
CrossObj(); }
static void CrossObj(){
// Crea un array di oggetti per immagazzinare quelli definiti
//negli altri linguaggi
VCBase[] objects = new VCBase[3];
// Carica nella posizione 0 dell'array l'oggetto
//creato usando IL
Console.WriteLine("\nCreating object: ILDerived");
objects[0] = new ILDerived();
// Carica nella posizione 1 dell'array l'oggetto
//creato usando C#
Console.WriteLine("\nCreating object: CSDerived");
objects[1] = new CSDerived();
// Carica nella posizione 2 dell'array l'oggetto
//creato usando VB
Console.WriteLine("\nCreating object: VBDerived");
objects[2] = new VBDerived();
// Chiama il metodo virtuale di ogni oggetto
Console.WriteLine("\nCalling Methods");
foreach(VCBase obj in objects){
obj.Method(); } } }
CrossLang.cs
21
Introduzione a C#
22
Introduzione a C#
Boxing ed Unboxing dei Value
23
Introduzione a C#
Boxing ed Unboxing dei Value
• Il Boxing dei value è un concetto essenziale nel sistema
dei tipi del C#. Con il boxing e l’unboxing si può
realizzare un collegamento tra i value type e i reference
type permettendo che il valore di un value type sia
convertito da e verso un oggetto.
• Convertire un value type in un reference type è detto
Boxing, il processo inverso Unboxing.
• Il Boxing avviene automaticamente quando un value type
è utilizzato in una locazione che richiederebbe l’uso di un
oggetto. Il Boxing di un value type consiste nell’allocare
l’istanza di un oggetto e copiare il valore nell’istanza.
24
Introduzione a C#
Boxing ed Unboxing dei Value
using System;
class Test
{
static void Main() {
int i = 1;
object o = i; // boxing
// verifica che o sia davvero un int
if (o is int) {
Console.Write("O is an int");
}
int j = (int) o; // unboxing
}
}
25
Introduzione a C#
Boxing ed Unboxing dei Value
26
Introduzione a C#
Boxing ed Unboxing dei Value
27
Introduzione a C#
Boxing ed Unboxing dei Value
using System;
public class UnboxingTest
{
public static void Main()
{ int intI = 123;
object o = intI;
// Riferimenti a oggetti incompatibili producono
// InvalidCastException
try
{
int intJ = (short) o;
Console.WriteLine("Unboxing OK.");
}
catch (InvalidCastException e)
{
Console.WriteLine("{0} Error: Incorrect
unboxing.",e);
} } }
Boxing Scorretto:
Errore di Runtime
28
Introduzione a C#
Differenze tra Value e
Reference Type
29
Introduzione a C#
Differenze tra Value e Reference Type
• Reference Type allocati nel Managed Heap,
l’operatore restituisce l’indirizzo di
memoria dell’oggetto (GC)
• Value Type allocati nello stack del thread, la
variabile che rappresenta l’oggetto ne
contiene direttamente il valore (nessuna
GC)
30
Introduzione a C#
Differenze tra Value e Reference Type
using System;
// E' un tipo Reference (a causa del 'class')
class RefType { public int x; }
// E' un tipo Value (a causa del 'struct')
struct ValType { public int x; }
class App {
static void Main() {
RefType rt1 = new RefType(); // Allocato nell'heap
ValType vt1 = new ValType(); // Allocato nello stack
rt1.x = 10;
// Cambia il riferimento a cui punta
vt1.x = 10;
// Cambiato il valore nello stack
RefType rt2 = rt1;
// Copia il solo puntatore
ValType vt2 = vt1;
// Alloca nello stack e copia i membri
rt1.x = 20;
vt1.x = 20;
Console.WriteLine("rt1.x = {0}, rt2.x = {1}", rt1.x, rt2.x);
Console.WriteLine("vt1.x = {0}, vt2.x = {1}", vt1.x, vt2.x);
Console.Write("Press Enter to close window...");
Console.Read();
} }
31
Introduzione a C#
Differenze tra Value e Reference Type
32
Introduzione a C#
Differenze tra Value e Reference Type
RefType
ValType
rt1.x =
vt1.x =
rt1 = new RefType();
vt1 = new ValType();
10;
10;
RefType
ValType
rt1.x =
vt1.x =
rt2 = rt1;
vt2 = vt1;
20;
20;
rt1.x
vt1.x
10
10
rt2.x
vt2.x
10
rt1.x
20
rt2.x
vt1.x
20
33
Introduzione a C#
Delegate
34
Introduzione a C#
Delegate
• Un oggetto delegate contiene informazioni
necessarie a richiamare uno specifico metodo di
un dato oggetto.
• Corrispondente “Type Safe” e Object oriented
del Function Pointer
• Permettono l’esecuzione dei Callback in maniera
sicura
• Sono definiti in runtime e si riferiscono solo a
metodi e non ad una intera classe.
35
Introduzione a C#
Delegate
• Un istanza di un delegate incapsula uno o più
metodi, ognuno noto come callable entity.
• L’oggetto delegate può essere passato al codice
che richiama il metodo in esso incapsulato senza
sapere in compile time quale metodo sarà
invocato.
• L’unica cosa che richiede al metodo che
incapsula è di essere compatibile con il tipo del
delegate
36
Introduzione a C#
Delegate
Dichiarazione
delegate void SimpleDelegate();
class Test
{
static void A() {
System.Console.WriteLine("Test.A");
}
static void Main() {
SimpleDelegate d = new SimpleDelegate(A);
d();
}
}
37
Introduzione a C#
Delegate
void MultiCall(SimpleDelegate d, int count) {
for (int i = 0; i < count; i++)
d();
}
}
• Il metodo Multicall non considera il tipo del metodo di destinazione per il
delegate SimpleDelegate, la sua accessibilità o il fatto che esso sia o meno
statico. Tutto ciò che importa che sia compatibile con SimpleDelegate
38
Introduzione a C#
class DChatServer {
public delegate void OnMsgArrived(String message);
private static OnMsgArrived onMsgArrived;
private DChatServer() {}
public static void ClientConnect(OnMsgArrived onMsgArrived) {
DChatServer.onMsgArrived = (OnMsgArrived)
Delegate.Combine(DChatServer.onMsgArrived, onMsgArrived);
}
public static void ClientDisconnect(OnMsgArrived onMsgArrived) {
DChatServer.onMsgArrived = (OnMsgArrived)
Delegate.Remove(DChatServer.onMsgArrived, onMsgArrived);
}
public static void SendMsg(String msg) {
// Invia un messaggio a TUTTI i client
SendMsg(msg, null);
}
public static void SendMsg(String msg, Object excludeClient) {
// Invia un messaggio a tutti i client tranne 'excludeClient'
if (excludeClient == null) {
onMsgArrived(msg);
} else {
Delegate[] DelegateList = onMsgArrived.GetInvocationList();
for (int i = 0; i < DelegateList.Length; i++) {
if (DelegateList[i].Target != excludeClient) {
((OnMsgArrived) DelegateList[i])(msg);
}
}
}
}
}
39
Introduzione a C#
class DChatClient {
private void onMsgArrived(String msg) {
Console.WriteLine("Msg arrived (Client {0}): {1}", clientName, msg);
}
private String clientName;
public DChatClient(String clientName) {
this.clientName = clientName;
DChatServer.ClientConnect(new DChatServer.OnMsgArrived(onMsgArrived));
}
public void Dispose() {
DChatServer.ClientDisconnect(new DChatServer.OnMsgArrived(onMsgArrived));
GC.SuppressFinalize(this);
}
~DChatClient() {
Dispose();
}
}
40
Introduzione a C#
private static void DelegateChatServerDemo() {
Console.WriteLine("Demo start: Delegate Chat Server.");
DChatClient cc1 = new DChatClient("1");
DChatClient cc2 = new DChatClient("2");
DChatClient cc3 = new DChatClient("3");
DChatServer.SendMsg("Hi to all clients");
DChatServer.SendMsg("Hi to all clients except client 2", cc2);
//
//
//
//
Sconnette esplicitamente i client dal chat server.
Se questo non viene fatto, la memoria dei client potrebbe
non essere liberata finché il server attivo, ovvero fino
alla chiusura dell'applicazione
cc1.Dispose();
cc2.Dispose();
cc3.Dispose();
Console.WriteLine("Demo stop: Delegate Chat Server.");
}
41
Introduzione a C#
class DChatServer {
public delegate void OnMsgArrived(String message);
private static OnMsgArrived onMsgArrived;
}
private DChatServer() {}
public static void ClientConnect(OnMsgArrived onMsgArrived) {
DChatServer.onMsgArrived = (OnMsgArrived)
Delegate.Combine(DChatServer.onMsgArrived, onMsgArrived);
}
public static void ClientDisconnect(OnMsgArrived onMsgArrived) {
DChatServer.onMsgArrived = (OnMsgArrived)
Delegate.Remove(DChatServer.onMsgArrived, onMsgArrived);
}
public static void SendMsg(String msg) {
// Invia un messaggio a TUTTI i client
SendMsg(msg, null);
}
public static void SendMsg(String msg, Object excludeClient) {
// Invia un messaggio a tutti i client tranne 'excludeClient'
if (excludeClient == null) {
onMsgArrived(msg);
} else {
Delegate[] DelegateList = onMsgArrived.GetInvocationList();
for (int i = 0; i < DelegateList.Length; i++) {
if (DelegateList[i].Target != excludeClient) {
((OnMsgArrived) DelegateList[i])(msg);
}
}
}
}
42
Introduzione a C#
private static void DelegateChatServerDemo() {
Console.WriteLine("Demo start: Delegate Chat Server.");
DChatClient cc1 = new DChatClient("1");
DChatClient cc2 = new DChatClient("2");
DChatClient cc3 = new DChatClient("3");
DChatServer.SendMsg("Hi to all clients");
DChatServer.SendMsg("Hi to all clients except client 2", cc2);
//
//
//
//
Sconnette esplicitamente i client dal chat server.
Se questo non viene fatto, la memoria dei client potrebbe
non essere liberata finché il server attivo, ovvero fino
alla chiusura dell'applicazione
cc1.Dispose();
cc2.Dispose();
cc3.Dispose();
Console.WriteLine("Demo stop: Delegate Chat Server.");
}
43
Introduzione a C#
class DChatClient {
private void onMsgArrived(String msg) {
Console.WriteLine("Msg arrived (Client {0}): {1}", clientName, msg);
}
private String clientName;
public DChatClient(String clientName) {
this.clientName = clientName;
DChatServer.ClientConnect(new DChatServer.OnMsgArrived(onMsgArrived));
}
public void Dispose() {
DChatServer.ClientDisconnect(new DChatServer.OnMsgArrived(onMsgArrived));
GC.SuppressFinalize(this);
}
~DChatClient() {
Dispose();
}
}
44
Introduzione a C#
class DChatServer {
public delegate void OnMsgArrived(String message);
private static OnMsgArrived onMsgArrived;
private DChatServer() {}
public static void ClientConnect(OnMsgArrived onMsgArrived) {
DChatServer.onMsgArrived = (OnMsgArrived)
Delegate.Combine(DChatServer.onMsgArrived, onMsgArrived);
}
}
public static void ClientDisconnect(OnMsgArrived onMsgArrived) {
DChatServer.onMsgArrived = (OnMsgArrived)
Delegate.Remove(DChatServer.onMsgArrived, onMsgArrived);
}
public static void SendMsg(String msg) {
// Invia un messaggio a TUTTI i client
SendMsg(msg, null);
}
public static void SendMsg(String msg, Object excludeClient) {
// Invia un messaggio a tutti i client tranne 'excludeClient'
if (excludeClient == null) {
onMsgArrived(msg);
} else {
Delegate[] DelegateList = onMsgArrived.GetInvocationList();
for (int i = 0; i < DelegateList.Length; i++) {
if (DelegateList[i].Target != excludeClient) {
((OnMsgArrived) DelegateList[i])(msg);
}
}
}
}
45
Introduzione a C#
private static void DelegateChatServerDemo() {
Console.WriteLine("Demo start: Delegate Chat Server.");
DChatClient cc1 = new DChatClient("1");
DChatClient cc2 = new DChatClient("2");
DChatClient cc3 = new DChatClient("3");
DChatServer.SendMsg("Hi to all clients");
DChatServer.SendMsg("Hi to all clients except client 2", cc2);
//
//
//
//
Sconnette esplicitamente i client dal chat server.
Se questo non viene fatto, la memoria dei client potrebbe
non essere liberata finché il server attivo, ovvero fino
alla chiusura dell'applicazione
cc1.Dispose();
cc2.Dispose();
cc3.Dispose();
Console.WriteLine("Demo stop: Delegate Chat Server.");
}
46
Introduzione a C#
class DChatServer {
public delegate void OnMsgArrived(String message);
private static OnMsgArrived onMsgArrived;
private DChatServer() {}
public static void ClientConnect(OnMsgArrived onMsgArrived) {
DChatServer.onMsgArrived = (OnMsgArrived)
Delegate.Combine(DChatServer.onMsgArrived, onMsgArrived);
}
public static void ClientDisconnect(OnMsgArrived onMsgArrived) {
DChatServer.onMsgArrived = (OnMsgArrived)
Delegate.Remove(DChatServer.onMsgArrived, onMsgArrived);
}
public static void SendMsg(String msg) {
// Invia un messaggio a TUTTI i client
SendMsg(msg, null);
}
public static void SendMsg(String msg, Object excludeClient) {
// Invia un messaggio a tutti i client tranne 'excludeClient'
if (excludeClient == null) {
onMsgArrived(msg);
} else {
Delegate[] DelegateList = onMsgArrived.GetInvocationList();
for (int i = 0; i < DelegateList.Length; i++) {
if (DelegateList[i].Target != excludeClient) {
((OnMsgArrived) DelegateList[i])(msg);
}
}
}
}
}
47
Introduzione a C#
private static void DelegateChatServerDemo() {
Console.WriteLine("Demo start: Delegate Chat Server.");
DChatClient cc1 = new DChatClient("1");
DChatClient cc2 = new DChatClient("2");
DChatClient cc3 = new DChatClient("3");
DChatServer.SendMsg("Hi to all clients");
DChatServer.SendMsg("Hi to all clients except client 2", cc2);
//
//
//
//
Sconnette esplicitamente i client dal chat server.
Se questo non viene fatto, la memoria dei client potrebbe
non essere liberata finché il server attivo, ovvero fino
alla chiusura dell'applicazione
cc1.Dispose();
cc2.Dispose();
cc3.Dispose();
Console.WriteLine("Demo stop: Delegate Chat Server.");
}
48
Introduzione a C#
class DChatClient {
private void onMsgArrived(String msg) {
Console.WriteLine("Msg arrived (Client {0}): {1}", clientName, msg);
}
private String clientName;
public DChatClient(String clientName) {
this.clientName = clientName;
DChatServer.ClientConnect(new DChatServer.OnMsgArrived(onMsgArrived));
}
public void Dispose() {
DChatServer.ClientDisconnect(new
DChatServer.OnMsgArrived(onMsgArrived));
GC.SuppressFinalize(this);
}
~DChatClient() {
Dispose();
}
}
49
Introduzione a C#
class DChatServer {
public delegate void OnMsgArrived(String message);
private static OnMsgArrived onMsgArrived;
private DChatServer() {}
public static void ClientConnect(OnMsgArrived onMsgArrived) {
DChatServer.onMsgArrived = (OnMsgArrived)
Delegate.Combine(DChatServer.onMsgArrived, onMsgArrived);
}
public static void ClientDisconnect(OnMsgArrived onMsgArrived) {
DChatServer.onMsgArrived = (OnMsgArrived)
Delegate.Remove(DChatServer.onMsgArrived, onMsgArrived);
}
}
public static void SendMsg(String msg) {
// Invia un messaggio a TUTTI i client
SendMsg(msg, null);
}
public static void SendMsg(String msg, Object excludeClient) {
// Invia un messaggio a tutti i client tranne 'excludeClient'
if (excludeClient == null) {
onMsgArrived(msg);
} else {
Delegate[] DelegateList = onMsgArrived.GetInvocationList();
for (int i = 0; i < DelegateList.Length; i++) {
if (DelegateList[i].Target != excludeClient) {
((OnMsgArrived) DelegateList[i])(msg);
}
}
}
}
50
Introduzione a C#
Delegate
51
Introduzione a C#
MultiThread
52
Introduzione a C#
MultiThread
• Essendo la gestione dei processi gestita dal
CLR, l’accesso a queste funzionalità da C#
è molto semplice
• Il namespace System.Threading fornisce
metodi per creare, eseguire, gestire e
sincronizzare thread
53
Introduzione a C#
MultiThread
using System;
using System.Threading;
class App {
//Codice del metodo eseguito nel primo Thread
public static void MyThreadMethod1()
{
for ( int i = 0; i<=30; i++ )
{
Console.WriteLine("thread 1");
}
}
//Codice del metodo eseguito nel secondo Thread
public static void MyThreadMethod2()
{
for ( int j = 0; j<=30; j++ )
{
Console.WriteLine("thread 2");
}
}
54
Introduzione a C#
MultiThread
static void Main() {
//Crea il primo thread
Thread thread1 = new Thread(new ThreadStart(MyThreadMethod1));
//Avvia il primo thread
thread1.Start();
//Crea il secondo thread
Thread thread2 = new Thread(new ThreadStart(MyThreadMethod2));
//Avvia il secondo thread
thread2.Start();
//Durante l'esecuzione dei 2 thread esegue un terzo ciclo
for ( int i = 0; i<=30; i++ )
{
Console.WriteLine("Main Thread");
}
}
}
55
Introduzione a C#
MultiThread
56
Introduzione a C#
Remoting
57
Introduzione a C#
Remoting
• Il Remoting fornisce una struttura che consente agli
oggetti di interagire tra di loro anche se risiedono su
diversi application domain
• La comunicazione avviene attraverso canali
• Prima che i messaggi tra le applicazioni remote vengano
inviati sui canali vengono codificati:
– In binario per le applicazioni critiche
– In XML dove è essenziale interoperabilità
• I messaggi XML utilizzano sempre SOAP
58
Introduzione a C#
Remoting
• I servizi di Remoting offerti dal framework nascondono al
programmatore la complessità dei metodi di chiamata
remoti.
• Quando un client attiva un oggetto remoto ne riceve un
proxy con il quale interagisce
• Per prima cosa si registra un canale di comunicazione
(HTTP, TCP), poi diventa possibile registrare gli oggetti
remoti
59
Introduzione a C#
Remoting
• Per la registrazione di un oggetto remoto servono i
seguenti dati:
– Il nome del tipo di oggetto remoto.
– L'oggetto URI (Uniform Resource Identifier) che i client utilizzeranno per
individuare l'oggetto.
– La modalità oggetto richiesta per l'attivazione da server, che può essere SingleCall
o Singleton.
60
Introduzione a C#
Remoting
• SigleCall
– Un oggetto SingleCall crea un'istanza di classe per ogni chiamata del client, anche
se le chiamate provengono dallo stesso client.
– L'invocazione successiva, sarà sempre servita da una differente istanza del server
anche se la precedente non è stata ancora riciclata dal sistema.
• Singleton
– Un oggetto Singleton invece non presenta mai più di una istanza
contemporaneamente
– Se una istanza è già esistente la richiesta viene soddisfatta da quella istanza. Se
l'istanza non esiste, alla prima richiesta viene creata dal server e tutte le
successive richieste vengono soddisfatte da quella istanza.
61
Introduzione a C#
using
using
using
using
System;
System.Runtime.Remoting;
System.Runtime.Remoting.Channels;
System.Runtime.Remoting.Channels.Tcp;
namespace RemotingSamples {
public class Sample {
server.cs
public static int Main(string [] args) {
// Crea e registra un nuovo canale Tcp
TcpChannel chan = new TcpChannel(8085);
ChannelServices.RegisterChannel(chan);
// Il metodo RegisterWellKnownServiceType permette di registrare l’oggetto per la
// futura attivazione [PARAMETRI (Tipo, URI, metodo di attivazione)]
RemotingConfiguration.RegisterWellKnownServiceType
(Type.GetType("RemotingSamples.HelloServer,object"),
"SayHello", WellKnownObjectMode.SingleCall);
System.Console.WriteLine("Hit to exit...");
System.Console.ReadLine();
return 0;
}
}
}
62
Introduzione a C#
using
using
using
using
System;
System.Runtime.Remoting;
System.Runtime.Remoting.Channels;
System.Runtime.Remoting.Channels.Tcp;
namespace RemotingSamples {
public class HelloServer : MarshalByRefObject {
object.cs
public HelloServer() {
Console.WriteLine("HelloServer activated");
}
public String HelloMethod(String name) {
Console.WriteLine("Hello.HelloMethod : {0}", name);
return "Hi there " + name;
}
}
}
63
Introduzione a C#
using
using
using
using
System;
System.Runtime.Remoting;
System.Runtime.Remoting.Channels;
System.Runtime.Remoting.Channels.Tcp;
client.cs
namespace RemotingSamples {
public class Client
{
public static int Main(string [] args)
{
TcpChannel chan = new TcpChannel();
ChannelServices.RegisterChannel(chan);
// Il client localizza l’oggetto remoto passando tipo e URL
HelloServer obj =
(HelloServer)Activator.GetObject(typeof(RemotingSamples.HelloServer)
, "tcp://localhost:8085/SayHello");
if (obj == null)
System.Console.WriteLine("Could not locate server");
else Console.WriteLine(obj.HelloMethod("Carlo"));
return 0;
}
}
}
64
Introduzione a C#
65
Introduzione a C#
Accesso alle API di Windows
66
Introduzione a C#
Accesso alle API di Windows
using System;
using System.Runtime.InteropServices;
class MainApp
{
[DllImport("user32.dll", EntryPoint="MessageBox", SetLastError=true, CharSet=CharSet.Auto)]
public static extern int MessageBox(int hWnd, String strMessage, String strCaption, uint uiType);
public static void Main()
{
MessageBox( 0, "Saluti da WinAPI!", ".NET Tutorial", 0 );
}
}
67
Introduzione a C#
Accesso alle API di Windows
68
Introduzione a C#
Exception
try {
// codice che può portare ad un errore
}
catch (Exception Type [ variable ]) {
// codice che deve essere eseguito quando avviene
l'errore
}
finally {
// codice da eseguire che avvenga o meno
// l'errore
}
69
Introduzione a C#
Exception
using System;
using System.IO;
public class App {
public static void Main() {
FileStream fs = null;
try {
fs = new FileStream(@"C:\NotThere.txt", FileMode.Open);
}
catch (Exception e) {
Console.WriteLine(e.Message);
}
finally {
if (fs != null) fs.Close();
}
}
}
70
Introduzione a C#
C# & ADO.NET
Interazione con i DataBase
71
Introduzione a C#
C# & ADO.NET
72
Introduzione a C#
C# & ADO.NET
73
Introduzione a C#
C# & ADO.NET
74
Introduzione a C#
C# & ADO.NET
75
Introduzione a C#
C# & ADO.NET
76
Introduzione a C#
Lettura dati da SQL Server
77
Introduzione a C#
using System;
using System.Data.SqlClient;
public class Test
{
public static void Main()
{
Test t=new Test();
t.Run();
}
public void Run()
{
SqlConnection conn = new SqlConnection("Data Source=BARIBAL; Integrated Security=SSPI; Initial
Catalog=master");
SqlCommand cmd = new SqlCommand("SELECT * FROM emp_test", conn);
try
{
conn.Open();
// Utilizziamo la classe DataReader per leggere la
// tabella un record per volta, e via via stamparne
// il contenuto sulla console
SqlDataReader myReader = cmd.ExecuteReader();
Console.WriteLine("Code \t Emp. Name \t Emp. Phone");
Console.WriteLine("-----------------------------------------");
78
Introduzione a C#
// Ad ogni record letto...
// (perchè in questo caso legge l'intera riga)
while (myReader.Read())
{
// ... estrae i valori e li stampa a schermo
Console.WriteLine("{0}\t{1}\t\t{2}", myReader.GetInt32(0), myReader.GetString(1),
myReader.GetString(2));
}
// Chiude il DataReader
myReader.Close();
// Chiude la Connessione
conn.Close();
}
catch(Exception e)
{
Console.WriteLine("Exception Occured -->> {0}",e);
}
}
}
79
Introduzione a C#
80
Introduzione a C#
Lettura dati da SQL Server
mediante OleDB Data Provider
81
Introduzione a C#
using System;
using System.Data.OleDb;
class OleDbTest{
public static void Main()
{
OleDbConnection aConnection = new OleDbConnection("Provider=SQLOLEDB.1;
Persist Security Info=False; User ID=sa;Initial Catalog=northwind;Data Source=BARIBAL");
OleDbCommand aCommand = new OleDbCommand("select * from orders", aConnection);
try{
aConnection.Open();
OleDbDataReader aReader = aCommand.ExecuteReader();
Console.WriteLine("This is the returned data from Northwind's Orders table");
while(aReader.Read()){
Console.WriteLine("{0}\t{1}", aReader.GetInt32(0),aReader.GetString(1));
}
aReader.Close();
aConnection.Close();
}
catch(OleDbException e)
{
Console.WriteLine("Error: {0}", e.Errors[0].Message);
}
}
}
82
Introduzione a C#
83
Introduzione a C#
Alcune operazioni più avanzate
Modifiche al database
“northwind” su SQL Server
84
Introduzione a C#
Popolare un DataSet
// Crea un DataSet (una cache) per memorizzare i dati da elaborare
DataSet objDataSet = new DataSet("OrderAdmin");
// Ora bisogna riempire la tabella, creando un
// comando SELECT * dalla tabella Orders…
string strOrders = "SELECT * FROM Orders ";
SqlCommand objOrderCommand = new SqlCommand(strOrders,objSqlConnection);
// e un DataAdapter nel quale mappare la tabella
SqlDataAdapter objOrdAdapter = new SqlDataAdapter();
objOrdAdapter.TableMappings.Add("Table","Orders");
// connettere il SqlCommand e l'SqlDataAdapter
objOrdAdapter.SelectCommand = objOrderCommand;
// e riempire il DataSet precedentemente creato
objOrdAdapter.Fill(objDataSet);
85
Introduzione a C#
Update
DataTable objOrdTable = objDataSet.Tables["Orders"];
DataTable objODTable = objDataSet.Tables["Order Details"];
// Ora aggiona il record della tabella Orders che ha OrderID=10248
foreach(DataRow objRow in objOrdTable.Rows)
{string strID = objRow["OrderID"].ToString();
string strShip = "HMS Invisible";
if(strID == "10248" )
{// Imposta le modifiche
string strUpDate = "UPDATE Orders SET ShipName = "+"'"+strShip+"'";
strUpDate+=" WHERE OrderID = " + strID;
objRow["ShipName"]=strShip ;
// Crea il comando SQL appropriato per l'aggiornamento
objOrdAdapter.UpdateCommand = new SqlCommand(strUpDate,objSqlConnection);
// Esegue l'aggiornamento
objOrdAdapter.Update(objDataSet,"Orders");
Console.WriteLine("Update done");
}
}
86
Introduzione a C#
Cancellare un record
DataTable objOrdTable = objDataSet.Tables["Orders"];
DataTable objODTable = objDataSet.Tables["Order Details"];
// Cancella i record dalla tabella Order Details che hanno OrderID 10248
for(int i=0;i<objODTable.Rows.Count;i++)
{
// Crea un DataRow con l'i-esima riga della tabella
DataRow objDataRow = objODTable.Rows[i];
string strID =objDataRow["OrderID"].ToString();
if( strID == "10248")
{// se ha OrderID = 10248 cancella il record dal DataSet...
objDataRow.Delete();
// ... ma solo dal DataSet! Per cancellarlo anche dalla sorgente dei dati,
// il database memorizzato sul server, bisogna aggiornarlo con il contenuto
// del dataset!
objODAdapter.DeleteCommand = new
SqlCommand("DELETE FROM [Order Details] WHERE OrderID = "+strID,objSqlConnection);
objODAdapter.Update(objDataSet,"Order Details");
Console.WriteLine("Delete done");
}
}
87
Introduzione a C#
Inserire un record
// Inserisce un nuovo record nella tabella con OrderID = 10248
// Per far questo si crea un oggetto DataRow con il metodo NewRow di DataTable,
// si riempe la riga con i dati appropriati e la si inserisce in DataTable.
DataRow objODRow = objODTable.NewRow();
objODRow["OrderID"] = 10248;
objODRow["ProductID"] = 63;
objODTable.Rows.Add(objODRow);
// Ora aggiorniamo anche la sorgente...
string strInsert = "INSERT INTO [Order Details]
(OrderID,ProductID,UnitPrice,Quantity,Discount) VALUES(10248,63,33.4,100,0.20)";
objODAdapter.InsertCommand = new SqlCommand(strInsert,objSqlConnection);
objODAdapter.Update(objDataSet,"Order Details");
Console.WriteLine("Insert done");
88
Introduzione a C#
Creare una relazione
DataColumn objDCParent;
DataColumn objDCChild;
// Crea una DataRelation per collegare le tabelle Orders e Order Details
DataRelation objDR;
// Riempiamo i due DataColumn dichiarati in precedenza
objDCParent=objDataSet.Tables["Orders"].Columns["OrderID"];
objDCChild=objDataSet.Tables["Order Details"].Columns["OrderID"];
// Per creare una relazione (DataRelation) denominata "OJoinOD" tra le due
//colonne
// OrderID delle tabelle Orders e Order Details
objDR=new DataRelation("OJoinOD", objDCParent,objDCChild);
objDataSet.Relations.Add(objDR);
89
Introduzione a C#
// Ora usiamo la relazione per stampare il ProductID prelevato da Order Details
// alla quale si è acceduto fornendo l'OrderID della tabella Orders.
// Al valore della colonna ProductID di Order Details ci si arriva seguendo la relazione.
Utilizzare
la relazione
// Per ogni riga nelle righe di Orders...
foreach(DataRow objRow in objOrdTable.Rows)
{//... se l'OrderID è pari a 10248...
string strOrderID = objRow["OrderID"].ToString();
if(strOrderID=="10248")
{//... Scrivi l'OrderID...
Console.WriteLine("Order Id:"+strOrderID);
// ... e per ogni riga nelle righe figlie della relazione OJoinOD...
// (ovvero per ogni riga di Order Details che ha OrderID=10248)
// (GetChildRows preleva le richieste righe figlie
//del DataRow seguendo la relazione indicata)
foreach(DataRow objChild in objRow.GetChildRows(objDataSet.Relations["OJoinOD"]))
{//... scrivi il ProductID
string strProductID=objChild["ProductID"].ToString();
Console.WriteLine(strProductID);
}
}
}
90
Introduzione a C#
91
Introduzione a C#
92
Introduzione a C#
..stavolta davvero!
93
Introduzione a C#
Bibliografia e Fonti
>>In principio fu System.Object
*Documentazione Microsoft di accompagnamento
a .NET Framework SDK
>>Hello, World
*Documentazione Microsoft di accompagnamento
a .NET Framework SDK
>>Sviluppo Cross Language
*Documentazione Microsoft di accompagnamento
a .NET Framework SDK
>>Boxing ed Unboxing dei Value
*Documentazione Microsoft di accompagnamento
a .NET Framework SDK
*http://www.oreillynet.com/pub/a/dotnet/2001/06/07/csharp_java.html?page=4
*http://www.c-sharpcorner.com/Language/BoxNUnBoxGAG.asp
94
Introduzione a C#
Bibliografia e Fonti
>>Differenza tra Value e Reference Type
*Documentazione Microsoft di accompagnamento
a .NET Framework SDK
>>Delegate
*Documentazione Microsoft di accompagnamento
a .NET Framework SDK
*http://www.ciol.com/content/technology/csharptutor/101103101.asp
*http://www.codeguru.com/cs_delegates/AS-Delegates.html
*http://www.devx.com/premier/mgznarch/vbpj/2001/09sep01/ce0109/ce0109-4.asp
*http://msdn.microsoft.com/msdnmag/issues/01/06/net/net0106.asp
95
Introduzione a C#
Bibliografia e Fonti
>>MultiThread
*Documentazione Microsoft di accompagnamento
a .NET Framework SDK
*http://www.c-sharpcorner.com/2/mt_beginner1.asp
*http://www.oreillynet.com/pub/a/dotnet/2001/08/06/csharp.html
*http://www.csharphelp.com/archives/archive128.html
*http://www.codeproject.net/dotnet/multithread.asp
*http://www.crackinguniversity2000.it/dotnet/Visual%20Studio_NET%20_NET%20Framework.htm
>>Remoting
*http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/hawkremoting.asp
>>C# & ADO .NET
*http://www.csharphelp.com/archives/archive103.html
*http://www.c-sharpcorner.com/Database/DBOpsInADOPA.asp
Tutti gli articoli citati sono di proprietà dei rispettivi autori.
96
Introduzione a C#
Credits
• Progetto eseguito nell’ambito del corso di
“Basi di Dati”
– Realizzato da Carlo Becchi
– Tutor del progetto: Ing. Mauro Coccoli
– Docente del corso: Prof. Antonio Boccalatte
• Laboratorio di Informatica DIST- Siemens/ORSI
– http://www.lido.dist.unige.it
Aprile 2002
97
Scarica

Non Compresso