Cours C#

Transcription

Cours C#
Nicolas Pastorelly
Introduction à C #
Principaux élément différentiables
Par rapport à Java
1
Modèle Objet
• Les types de bases ne peuvent pas être utilisés comme
des objets en Java
Integer i_ref = new Integer(7);
List l = ...
l.add( i_ref );
…… i_ref.intValue();
• C# : boxing & unboxing
i
123
int i = 123;
object o = i;
int j = (int)o;
System.Int32
o
j
Stack
Heap
123
123
2
Les propriétés
Public class Test{
// donnée privée.
private int m_number = 0;
[Description(“Un entier non négatif !")]
public int Number{
// accesseurs du champ privé
Test T = new Test();
get {
if (m_number < 0) return 0;
return m_number;
}
set {
if (value < 0) m_number = 0;
else m_number = value;
}
}
T.Number = -2;
Int I = T.Number + 1;
}
3
Les indexers
public class ListBox: Control
{
private string[] items;
public string this[int index] {
get {
return items[index];
}
set {
items[index] = value;
Repaint();
}
}
ListBox listBox = new ListBox();
listBox[0] = "hello";
Console.WriteLine(listBox[0]);
}
4
Les classes non extensibles
sealed class Student
{
string fname;
string lname;
int uid;
void attendClass() {}
}
? (final Java)
5
Les NameSpaces
using System;
namespace Company
{
public class MyClass
{ /* Company.MyClass */
int x;
void doStuff(){}
}
namespace Carnage4life
{
public class MyOtherClass
{ /* Company.Carnage4life.MyOtherClass */
int y;
void doOtherStuff(){}
public static void Main(string[] args)
{
Console.WriteLine("Hey, I can nest
namespaces");
}
}// class MyOtherClass
}// namespace Carnage4life
}// namespace Company
6
Constructeurs, Destructeurs
public class MyClass
{
static int num_created = 0;
int i = 0;
MyClass()
{
i = ++num_created;
Console.WriteLine("Created object #" + i);
}
~MyClass()
{
Console.WriteLine("Object #" + i + " is being finalized");
}
public static void Main(string[] args)
{
for(int i=0; i < 10000; i++)
new MyClass();
}
7
Constructeur de classe
using System;
class SomeClass {
private Int32 member1;
private static Int32 member2;
//Type constructor
static SomeClass(){}
//Instance constructor
public SomeClass(){}
//default instance Constructor
public SomeClass(Int32 memberval)
{ member1 = memberval;}
//Other class operations ...
}
8
Constructeurs de classe
class StaticInitTest
{
string instMember = InitInstance();
string staMember = InitStatic();
StaticInitTest()
{
6
Console.WriteLine("In instance constructor");
}
static StaticInitTest()
{
1
Console.WriteLine("In static constructor");
}
static String InitInstance()
{
4
Console.WriteLine("Initializing instance variable");
return "instance";
}
static String InitStatic()
{
5 static variable");
Console.WriteLine("Initializing
return "static";
}
static void DoStuff()
{
3
Console.WriteLine("Invoking static DoStuff() method");
}
public static void Main(string[] args)
{
Console.WriteLine("Beginning main()"); 2
StaticInitTest.DoStuff();
StaticInitTest sti = new StaticInitTest();
Console.WriteLine("Completed main()");
}
}
In static constructor
Beginning main()
Invoking static DoStuff() method
Initializing instance variable
Initializing static variable
In instance constructor
Completed main()
9
Constructeurs de classe
class Bidon {}/* juste pour avoir un objet à créer et illustrer le readonly */
class ClassLoaderTest{
private static int compteur;
private static readonly int constante; //équivalent à une constante pas initialisée
private static readonly Bidon bidon;
/* CONSTRUCTEUR DE CLASSE : remarquez le static !!*/
static ClassLoaderTest(){
Console.WriteLine("Constructeur de classe (compteur <-- 1)");
constante = 12345;
compteur = 1;
bidon = new Bidon();
}
/* UN CONSTRUCTEUR D'INSTANCE */
public ClassLoaderTest(){
Console.WriteLine(constante + ": Constructeur d'instances #"+ compteur++);
}
public static void Main (String[] args){
Console.WriteLine ("Dans le main");
ClassLoaderTest clt01 = new ClassLoaderTest();
ClassLoaderTest clt02 = new ClassLoaderTest();
}
}
d:\C#Work\classloader>Constructeur de classe (compteur <-- 1)
##==> Le constructeur de classe n'est appelé qu'une fois !
Dans le main
12345: Constructeur d'instances #1
12345: Constructeur d'instances #2
10
Constantes
public class ConstantTest
{
/* Compile time constants */
const int i1 = 10; //implicitly a static variable
// code below won't compile because of 'static' keyword
// public static const int i2 = 20;
/* run time constants */
public static readonly uint l1 = (uint) DateTime.Now.Ticks;
/* object reference as constant */
readonly Object o = new Object();
/* uninitialized readonly variable */
readonly float f;
ConstantTest()
{
// unitialized readonly variable must be initialized in constructor
f = 17.21;
}
}
11
Implémentation & Héritage
/*** JAVA ***/
class A {}
interface I {}
interface J {}
class B extends A implements I, J {}
/*** C# ***/
class A {}
interface I {}
interface J {}
class B : A, I, J {}
12
appel du constructeur père
class MyException: Exception
{
private int Id;
public MyException(string message): this(message, null, 100){ }
public MyException(string message, Exception innerException):
this(message, innerException, 100){ }
public MyException(string message, Exception innerException, int id) :
base(message, innerException)
{
this.Id = id;
}
}
13
méthode virtuelles (et finales)
using System;
public class Parent
{
public void DoStuff(string str)
{
Console.WriteLine("In Parent.DoStuff: " + str);
}
}
public class Child: Parent
{
public void DoStuff(int n)
{
Console.WriteLine("In Child.DoStuff: " + n);
}
public void DoStuff(string str)
{
Console.WriteLine("In Child.DoStuff: " + str);
}
}
public class VirtualTest
{
public static void Main(string[] args)
{
Child ch = new Child();
ch.DoStuff(100);
ch.DoStuff("Test");
((Parent) ch).DoStuff("Second Test");
}
}//VirtualTest
OUTPUT:
In Child.DoStuff: 100
In Child.DoStuff: Test
In Parent.DoStuff: Second Test
class Parent
{
public void DoStuff(String str)
{
System.out.println("In Parent.DoStuff: " + str);
}
}
class Child extends Parent
{
public void DoStuff(int n)
{
System.out.println("In Child.DoStuff: " + n);
}
public void DoStuff(String str)
{
System.out.println("In Child.DoStuff: " + str);
}
}
public class VirtualTest
{
public static void main(String[] args)
{
Child ch = new Child();
ch.DoStuff(100);
ch.DoStuff("Test");
((Parent) ch).DoStuff("Second Test");
}
}//VirtualTest
OUTPUT:
In Child.DoStuff: 100
In Child.DoStuff: Test
In Child.DoStuff: Second Test
14
méthode virtuelles (et finales)
using System;
public class Parent
{
public virtual void DoStuff(string str)
{
Console.WriteLine("In Parent.DoStuff: " + str);
}
}
public class Child: Parent
{
public void DoStuff(int n)
{
Console.WriteLine("In Child.DoStuff: " + n);
En utilisant new, nous
retombons dans la
situation de l’exemple
précédent
}
public override void DoStuff(string str)
{
Console.WriteLine("In Child.DoStuff: " + str);
}
}
public class VirtualTest
{
public static void Main(string[] args)
{
Child ch = new Child();
ch.DoStuff(100);
ch.DoStuff("Test");
((Parent) ch).DoStuff("Second Test");
}
}//VirtualTest
In Child.DoStuff: 100
In Child.DoStuff: Test
In Child.DoStuff: Second Test
15
Classes imbriquée
public class Car
{
private Engine engine;
private class Engine
{
string make;
}
}
NB : en C# pas de création de classe dans un méthode
16
surcharge d'opérateurs
class OverloadedNumber
{
private int value;
public OverloadedNumber(int value)
{
this.value = value;
}
public override string ToString()
{
return value.ToString();
}
public static OverloadedNumber operator (OverloadedNumber number)
{
return new OverloadedNumber(-number.value);
}
public static OverloadedNumber operator
+(OverloadedNumber number1,
OverloadedNumber number2)
{
return new OverloadedNumber(number1.value +
number2.value);
}
public static OverloadedNumber operator
++(OverloadedNumber number)
{
return new OverloadedNumber(number.value +
1);
}
}
public class OperatorOverloadingTest
{
public static void Main(string[] args)
{
OverloadedNumber number1 = new
OverloadedNumber(12);
OverloadedNumber number2 = new
OverloadedNumber(125);
Console.WriteLine("Increment: {0}", ++number1);
Console.WriteLine("Addition: {0}", number1 +
number2);
}
} // OperatorOverloadingTest
17
L'instruction "switch"
switch(foo)
{
case "A":
Console.WriteLine("A seen");
break;
case "B":
case "C":
Console.WriteLine("B or C seen");
break;
/* ERROR: Won't compile due to fall-through at case "D" */
case "D":
Console.WriteLine("D seen");
case "E":
Console.WriteLine("E seen");
break;
}
18
Goto (à ne pas utiliser !)
class GotoSample
{
public static void Main(string[] args)
{
int num_tries = 0;
retry:
try
{
num_tries++;
Console.WriteLine("Attempting to connect to
network. Number of tries =" + num_tries);
//Attempt to connect to a network times out
//or some some other network connection error that
//can be recovered from
throw new SocketException();
}
catch(SocketException)
{
if(num_tries < 5)
goto retry;
}
}/* Main(string[]) */
}//GotoSample
19
De l’indentification de type
if(x is MyClass)
{
MyClass mc = (MyClass) x;
}
Ou
MyClass mc = o as MyClass;
if(mc != null) //check if cast successful
mc.doStuff();
20
Accès aux classes
Mode
Explication
public
pareil que Java
private
pareil que Java
internal
accessible pour tout ce qui est dans la même
assembly
protected
accessible par toutes les sous-classes seulement
(différent de Java car en Java les membres protected
sont aussi visibles à l'intérieur d'un même fichier)
internal
protected
équivalent au protected de Java. Les droits sont égaux
à ceux de internal + ceux de protected
21
Itération dans une collection
Java import
public
int
for
java.util.Vector;
static int sum(Vector v) {
sum = 0;
(int j = 0; j < v.size(); j++) {
Integer i = (Integer)v.elementAt(j);
sum = sum + i.intValue();
}
return sum;
}
C#
using System.Collections;
static int SumList(ArrayList theList) {
int sum = 0;
foreach (int j in theList) {
sum = sum + j;
}
return sum;
}
22
Les fonctions déléguées
//delegate base
public class HasDelegates
{
// delegate declaration, similar to a function pointer declaration
public delegate bool CallbackFunction(string a, int b);
//method that uses the delegate
public bool execCallback(CallbackFunction doCallback, string x, int y)
{
Console.WriteLine("Executing Callback function...");
if (doCallback == null)
throw ArgumentException("Callback can't be null!");
return doCallback(x, y);
}
}
public class DelegateTest
{
public static void Main(string[] args)
{
HasDelegates MyDel = new HasDelegates();
//create delegate
public class FunctionDelegates
{
public static bool FunctionFoo(string a, int b)
{
Console.WriteLine("Foo: {0} {1}", a,
b);
return true;
}
}
HasDelegates.CallbackFunction myCallback =
new HasDelegates.CallbackFunction (FunctionDelegates.FunctionFoo);
//pass delegate to delegate function
MyDel.execCallback(myCallback, "Twenty", 20);
}
} // DelegateTest
23
Les fonctions déléguées
//la déclaration de la delegate
public delegate void Void_IntString (int n, String s);
//une classe qui utilise le delegate.
//Vous pouvez ainsi choisir quelle type d'action associer à un même code
class Test {
public static Void_IntString TraiterDonnees= new Void_IntString(Deleg01.afficheAge);
public static void Main (String [] args) {
Console .WriteLine("Un exemple d'utilisation de *delegate*");
TraiterDonnees (21, "Alain");
}
}
class Deleg01 {
public static void afficheAge (int x, String y) {
//affichage à la console
Console .WriteLine ("{1} a {0} ans", x, y);
}
}
class Deleg02 {
public static void enregistreFicher (int x, String y) {
//enregistrement des données dans un fichier
//...
}
}
Alain a 21 ans
24
.NET-Types non disponibles en Java
QQchoseSePasse
• Delegates & Events:
JeRéagis
JEcouteEtRéagisAuxEvts
class JEnvoieUnEvt{
...
public event FctADeclancherQuandQQchoseSePasse QQchoseSePasse;
JEnvoieUnEvt
QQchoseSePasse
Je m‘abonne
(+=)
public delegate void FctADeclancherQuandQQchoseSePasse (int param);
...
}
}
class JEcouteEtRéagisAuxEvts{
...
JEnvoieUnEvt Sender; // + création etc.
...
Sender. QQchoseSePasse += new
FctADeclancherQuandQQchoseSePasse (this.JeRéagis);
Public void JeRéagis (int x){…………….}
}
25
Les Events
• Définir une signature
public delegate void EventHandler (object sender, EventArgs e);
Définir l’événement & la logique de déclanchement
n
public class Button
{
public event EventHandler Click;
protected void OnClick(EventArgs e) {
if (Click != null) Click (this, e);
}
}
26
Les Events
public class MyForm: Form
{
Button okButton;
public MyForm() {
okButton = new Button(...);
okButton.Caption = "OK";
okButton.Click += new EventHandler(OkButtonClick);
}
void OkButtonClick(object sender, EventArgs e) {
ShowMessage("You pressed the OK button");
}
}
27
Les Alias
using Terminal = System.Console;
class Test
{
public static void Main(string[] args)
{
Terminal.WriteLine("Terminal.WriteLine is equivalent to
System.Console.Writeline");
}
}
28
Pointeur et code non protégé (unsafe)
class UnsafeTest
{
public static unsafe void Swap(int* a, int*b)
{
int temp = *a;
*a = *b;
*b = temp;
}
public static unsafe void Sort(int* array, int size)
{
for(int i= 0; i < size - 1; i++)
for(int j = i + 1; j < size; j++)
if(array[i] > array[j])
Swap(&array[i], &array[j]);
}
public static unsafe void Main(string[] args)
{
int[] array = {9, 1, 3, 6, 11, 99, 37, 17, 0, 12};
Console.WriteLine("Unsorted Array:");
foreach(int x in array)
Console.Write(x + " ");
fixed( int* iptr = array )
{ // must use fixed to get address of array
Sort(iptr, array.Length);
}//fixed
Console.WriteLine("\nSorted Array:");
foreach(int x in array)
Console.Write(x + " ");
}}
29
Passage par référence
class PassByRefTest
{
public static void ChangeMe(out string s)
{
s = "Changed";
}
public static void Swap(ref int x, ref int y)
{
int z = x;
x = y;
y = z;
OUTPUT
a := 10, b := 5, s = Changed
}
public static void Main(string[] args)
{
int a = 5, b = 10;
string s;
Swap(ref a, ref b);
ChangeMe(out s);
Console.WriteLine("a := " + a + ", b := " + b + ", s = " + s);
}
}
30
listes variables de paramètres
class ParamsTest
{
public static void PrintInts(string title, params int[] args)
{
Console.WriteLine(title + ":");
foreach(int num in args)
Console.WriteLine(num);
}
public static void Main(string[] args)
{
PrintInts("First Ten Numbers in Fibonacci Sequence", 0, 1, 1,
2, 3, 5, 8, 13, 21, 34);
}
}
31
L'implémentation explicite d'interfaces
interface IVehicle
{
//identify vehicle by model, make, year
void IdentifySelf();
}
void IVehicle.IdentifySelf ()
{
Console.WriteLine("Model:" + this.model + " Make:" +
this.make
+ " Year:" + this.year);
}
interface IRobot
{
//identify robot by name
void IdentifySelf();
}
class TransformingRobot : IRobot, IVehicle
{
string model;
string make;
short year;
string name;
TransformingRobot(String name, String model, String
make, short year)
{
this.name = name;
this.model = model;
this.make = make;
this.year = year;
}
public static void Main()
{
TransformingRobot tr = new TransformingRobot
("SedanBot","Toyota", "Corolla", 2001);
// tr.IdentifySelf(); ERROR
IVehicle v = (IVehicle) tr;
IRobot r = (IRobot) tr;
v.IdentifySelf();
r.IdentifySelf();
}
}
OUTPUT
Model:Toyota Make:Corolla Year:2001
My name is SedanBot
void IRobot.IdentifySelf ()
{
Console.WriteLine("My name is " + this.name);
}
32
Integration Windows
using System;
//necessaire pour le DllImport
using System.Runtime.InteropServices;
class SndPlay{
[DllImport("winmm.dll")]
public static extern long PlaySound(String lpszName, long hModule, long dwFlags);
public static void Main (String []args) {
String fName = @"d:\C#Work\callapi\snd.wav";
PlaySound(fName, 0, 0);
}
}
33
Les commentaires
class XmlElement
{
/// <summary>
///
Returns the attribute with the given name and
///
namespace</summary>
/// <param name="name">
///
The name of the attribute</param>
/// <param name="ns">
///
The namespace of the attribute, or null if
///
the attribute has no namespace</param>
/// <return>
///
The attribute value, or null if the attribute
///
does not exist</return>
/// <seealso cref="GetAttr(string)"/>
///
public string GetAttr(string name, string ns) {
...
}
}
34