- Stahuj zápisky z přednášek a ostatní studijní materiály
- Zapisuj si jen kvalitní vyučující (obsáhlá databáze referencí)
- Nastav si své předměty a buď stále v obraze
- Zapoj se svojí aktivitou do soutěže o ceny
- Založ si svůj profil, aby tě tví spolužáci mohli najít
- Najdi své přátele podle místa kde bydlíš nebo školy kterou studuješ
- Diskutuj ve skupinách o tématech, které tě zajímají
Studijní materiály
Zjednodušená ukázka:
Stáhnout celý tento materiálom „zavolali“ metodu. Jako název použijeme
jméno události, parametry definuje typ delegáta, který je
posluchačem události.
Programové konstrukce 141
Delegáti – Události
(Posluchač)
class Customer
{
string name;
public Customer(string name,Producer producer)
{
this.name=name;
//Registrace noveho delegata u udalosti
producer.ItemProduced+=new
Producer.WantToKnow(NewItemProduced);
}
//Obsluha udalosti
public void NewItemProduced(Producer producer,InfoEventArgs info)
{
Console.WriteLine(this.name+": "+producer.Name+" produce
item:"+info.Info);
}
}
Programové konstrukce 142
Delegáti – Události (4)
z Pokud chce nějaký objekt reagovat na generované
události, musí se stát „posluchačem“ dané události.
z To vlastně znamená, že musí vytvořit delegáta příslušného
typu (v našem případě WantToKnow) a tohoto delegáta
zaregistrovat u události.
z V našem příkladě je vytvořen objekt typu
Producer.WantToKnow obsahující referenci na metodu
NewItemProduced.
z Vytvořený delegát je přidán operátorem += k události
producer.ItemProduced (jde o instanční položku objektu
producer)
Programové konstrukce 143
Delegáti – Události (Spuštění
aplikace)
class RunApp {
public static void Main() {
Producer producer=new Producer("Haven inc.");
Customer marek=new Customer("Marek",producer);
Customer tom=new Customer("Tom",producer);
producer.Produce("Ferrari");
producer.Produce("pencil");
producer.Produce("cake");
}
}
z Výstupem programu bude:
Production of Ferrari started.
Production of Ferrari ended.
Marek: Haven inc. produce item:Ferrari
Tom: Haven inc. produce item:Ferrari
Production of pencil started.
Production of pencil ended.
Marek: Haven inc. produce item:pencil
Tom: Haven inc. produce item:pencil
Production of cake started.
Production of cake ended.
Marek: Haven inc. produce item:cake
Tom: Haven inc. produce item:cake
Programové konstrukce 144
Delegáti – Události (5)
z V hlavní části programu pak nejprve
vytvoříme instanci zdroje událostí, objekt
producer typu Producer.
z Pak vytvoříme dva posluchače. Objekty
marek a tom typu Customer.
z Tyto objekty se zaregistrují u zdroje událostí.
z Následně jsou vygenerovány tři události
pomocí volání metody Produce.
Programové konstrukce 145
Generické datové typy –Proč
používat
z Například při použití kolekcí dochází obvykle
k přetypování na object.
z Sice tak můžeme s daným objektem pracovat v
různých kontextech, nutné je ovšem jeho
přetypování.
z Nutná typová kontrola za běhu aplikace.
z Chyby, které by mohly být odhaleny již při překladu.
z Zdrojový kód zaplaven typovými konverzemi.
z Řešením tohoto typu problému jsou
generické datové typy.
Programové konstrukce 146
Generické datové typy –
Základní vlastnosti
z Mluvíme-li o generickém kódu, máme namysli kód,
který využívá parametrizované typy.
z Parametrizované typy jsou nahrazeny konkrétními typy v
době použití kódu.
z hodnotový typ, referenční typ, typový parametr.
z -třídy, struktury, rozhraní, metody a delegáty
z Na jednotlivé parametrizované typy navíc můžeme klást
různá omezení.
z V rámci jedné definice můžeme použít několik
parametrizovaných typů ().
Programové konstrukce 147
Generické datové typy –
Jednoduchý příklad (1)
public class Stack
{
object[] items;
int count;
public void Push(object item) {...}
public object Pop() {...}
}
Stack stack = new Stack();
stack.Push(3);
int i = (int)stack.Pop();
Stack stack2 = new Stack();
stack2.Push(new Customer()); // class for customer
string s = (string)stack2.Pop(); // bad explicit cast, but not error
Programové konstrukce 148
Generické datové typy –
Jednoduchý příklad (2)
public class Stack
{
T[] items;
int count;
public void Push(T item) {...}
public T Pop() {...}
}
Stack stack = new Stack();
stack.Push(3);
int x = stack.Pop();
string y = stack.Pop(); //type mismatch
Programové konstrukce 149
Generické datové typy –
Jednoduchý příklad (3)
z Generické datové typy mohou mít více typových parametrů.
public class Dictionary
{
public void Add(K key, V value) {...}
public V this[K key] {...}
}
z Použití by pak vypadalo třeba takto:
Dictionary dict = new
Dictionary();
dict.Add("Peter", new Customer());
Customer c = dict["Peter"];
Programové konstrukce 150
Generické datové typy –
Omezení (1)
z Někdy potřebujeme na typované parametry klást jistá omezení.
public class Dictionary
{
public void Add(K key, V value)
{
…
if (key.CompareTo(x) < 0) {...}
// Error, no CompareTo method
…
}
}
z Tyto omezení můžeme specifikovat pomocí konstrukce where.
Programové konstrukce 151
Generické datové typy –
Omezení (2)
z where T: struct - parametrizovaný typ T musí být hodnotový typ.
z where T : class - T musí být referenční typ. Může jít o třídu,
rozhraní, delegáta a nebo pole.
z where T : new() - T musí mít veřejný konstruktor bez paramtrů.
Pokud toto omezení používáme v kombinaci s ostatními, musí
být poslední.
z where T : - T musí být odvozen ze
specifikované třídy.
z where T : - T musí implementovat dané
rozhraní. Lze specifikovat několik těchto omezení najednou.
z where T : U - T musí být odvozen z dodaného
parametrizovaného typu pro U.
Programové konstrukce 152
Generické datové typy –
Omezení (3)
z Řešením předcházejícího problému může být, že budeme
vyžadovat aby typový parametr K implementoval rozhraní
IComparable.
public class Dictionary
where K: IComparable
{
public void Add(K key, V value)
{
...
if (key.CompareTo(x) < 0) {...}
...
}
}
Programové konstrukce 153
Generické datové typy –
Omezení (4)
class EntityTable
where K: IComparable, IPersistable
where E: Entity, new()
class EmployeeList
where T : Employee, IEmployee, System.IComparable,
new()
public static void OpTest(T s, T t) where T : class
{
System.Console.WriteLine(s == t);
}
class List
{
void Add(List items) where U : T {/*...*/}
}
public class SampleClass where T : V { }
Programové konstrukce 154
Generické datové typy –
Generické metody
z Předchozí definici třídy Stack bychom mohli rošířit například
takto:
void PushMultiple(Stack stack, params T[]
values)
{
foreach (T value in values)
stack.Push(value);
}
Stack stack = new Stack();
PushMultiple(stack, 1, 2, 3, 4);
z Můžeme rovněž volat takto:
PushMultiple(stack, 1, 2, 3, 4);
Programové konstrukce 155
Generické datové typy –Volání
generických metod
class Test
{
static void F(int x, T y)
{
Console.WriteLine("one");
}
static void F(T x, long y)
{
Console.WriteLine("two");
}
static void Main()
{
F(5, 324); // Ok, prints "one"
F(5, 324); // Ok, prints "two"
F(5, 324); // Ok, prints "one“
F(5, 324); // Error, ambiguous
F(5, 324L); // Error, ambiguous
}
}
Programové konstrukce 156
Generické datové typy –
Signatura generických metod
z Omezení jsou u signatur generických metod ignorována.
z Významný je počet generických typových parametrů jako i
seřazení pozic typových parametrů.
class A {}
class B {}
interface IX {
T F1(T[] a, int i); // Error
void F1(U[] a, int i); // Error
void F2(int x); // Ok
void F2(int x); // Ok
void F3(T t) where T: A; // Error
void F3(T t) where T: B; // Error
}
Programové konstrukce 157
Generické datové typy –
Signatura generických metod
z Omezení jsou u signatur generických metod ignorována.
z Významný je počet generických typových parametrů jako i
seřazení pozic typových parametrů.
class A {}
class B {}
interface IX {
T F1(T[] a, int i); // Error
void F1(U[] a, int i); // Error
void F2(int x); // Ok
void F2(int x); // Ok
void F3(T t) where T: A; // Error
void F3(T t) where T: B; // Error
}
z Podobně je tomu i u jiných generických typů.
Programové konstrukce 158
Generické datové typy –
Signatura generických metod
z Omezení jsou u signatur generických metod ignorována.
z Významný je počet generických typových parametrů jako i
seřazení pozic typových parametrů.
class A {}
class B {}
interface IX {
T F1(T[] a, int i); // Error
void F1(U[] a, int i); // Error
void F2(int x); // Ok
void F2(int x); // Ok
void F3(T t) where T: A; // Error
void F3(T t) where T: B; // Error
}
z Podobně je tomu i u jiných generických typů.
Programové konstrukce 159
Generické datové typy –
Vložený typ
class Outer
{
class Inner
{
public static void F(T t, U u) {...}
}
static void F(T t) {
Outer.Inner.F(t, "abc"); // These two statements have
Inner.F(t, "abc"); // the same effect
Outer.Inner.F(3, "abc"); // This type is different
Outer.Inner.F(t, "abc"); // Error, Outer needs type arg
}
}
Programové konstrukce 160
Generické datové typy –Další
vlastnosti
z Statické položky
z Statické položky jsou sdíleny mezi instancemi
stejného uzavřeného zkonstruovaného typu.
z Statický konstruktor je vykonán právě jednou pro
každý uzavřená zkonstruovaný typ.
Programové konstrukce 161
Generické datové typy –
Implicitní hodnoty
z Implicitní hodnoty využívají klíčového slova default . Vrací implicitní
hodnotu konkrétního typového parametru.
z null pro odkazové typy
z 0 pro číselné typy
z false pro booleovské typy
z '\0' znakové typy
z strukturu inicializovanou implicitní hodnotou
public class C
{
private T value;
public T M() {
return (condition) ? value : default(T);
}
}
Programové konstrukce 162
Generické datové typy –
Negenerické typy
z Vlastnosti, události, indexery, operátory, konstruktory a
destruktory nemohou sami mít typové parametry.
z Mohou se ovšem vyskytovat v generických typech a využívat
typového parametru.
public class Dictionary
{
public void Add(K key, V value) {...}
public V this[K key] {...}
}
Programové konstrukce 163
Atributy
z Platforma .NET definuje možnost asociovat libovolné informace
(metadata) se zdrojovým kódem aplikace.
z Tyto metadata jsou realizována pomocí atributů.
z Tyto metadata jsou pak součástí assembly.
z Tyto metadata jsem v aplikaci schopni získat pomocí mechanismu
reflexe.
z Příklad
z Jak již bylo řečeno, součástí assembly jsou metadata určující verzi,
výrobce, ... .
z Vytvoříme-li projekt pomocí Visual Studia.NET, vytvoří tento nástroj
soubor AssemblyInfo.cs. Tento soubor obsahuje atributy vztahující se
k celé assembly.
z Tyto atributy mají následující formát:
[assembly: AssemblyVersion("1.0.*")]
z Chceme-li definovat atribut pro celou assembly, musíme na začátku
uvést assembly:.
z Následuje název atributu a jeho hodnota.
Programové konstrukce 164
Atributy – AssemblyInfo.cs (1)
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]
Programové konstrukce 165
Atributy –Příklady použití
atributů (1)
z Atribut Serializable
z Tento atribut použijeme pokud chceme, aby nějaká třída (její instance) byla
serializována.
[Serializable]
class MyClass() ...
z Atribut Obsolete
z Atribut určující, že daná metoda je již zastaralá a nebude v další verzi
použita.
[Obsolete(message,bool)
z message - vysvětlující text, který bude vypisovat překladač.
z bool je true - použití metody je chyba při překladu.
z bool je false - použití metody způsobí warning při překladu.
class Test
{
[Obsolete("This method can not be used!",true)]
public void SomeMethod() {}
}
Programové konstrukce 166
Atributy – Realizace atributů
(1)
z Atributy jsou realizovány jako normální třídy.
z Základní třídou pro všechny atributy je třída System.Attribute.
z Množinu atributů je možno libovolně rozšiřovat.
class MyAttribute : Attribute
{
private string message;
public MyAttribute(string message)
{
this.message=message;
}
public string Message
{
get
{return this.message;}
}
}
[MyAttribute("Simple class")]
class Example
{
[MyAttribute("Stupid method")]
public void SomeMethod() {}
}
Programové konstrukce 167
Atributy – Realizace atributů
(2)
class RunApp
{
static void Main(string[] args)
{
Type example=typeof(Example);
foreach(MyAttribute myAttribute in
example.GetCustomAttributes(false))
Console.WriteLine("Class: "+myAttribute.Message);
foreach(MemberInfo member in example.GetMembers())
foreach(MyAttribute myAttribute in
member.GetCustomAttributes(false))
Console.WriteLine("Member: "+myAttribute.Message);
}
}
z Výstup programu bude:
Class: Simple class
Member: Stupid method
Programové konstrukce 168
Atributy –Poziční a
pojmenované parametry (1)
z Existují dva typy parametrů atributů.
z Poziční parametry se zadávají jako formální
parametry konstruktoru a jsou tudíž vždy
povinné.
z Pojmenované parametry se zadávají pomocí
jména a operátoru přiřazení.
Programové konstrukce 169
Atributy –Poziční a
pojmenované parametry (2)
class MyAttribute : Attribute
{
private string message;
public MyAttribute(string message)
{
this.message=message;
}
int number;
public int Number
{
get {return number;}
set {number=value;}
}
public string Message
{
get {return this.message;}
}
}
z Atribut pak můžeme použít takto:
[MyAttribute("some message")]
[MyAttribute("some message",Number=3)]
Programové konstrukce 170
Atributy – Atributy atributů (1)
z Každému atributu můžeme nastavovat určité
vlastnosti (metadata k metadatům v podobě
atributů:-).
[AttributeUsage(destination,
AllowMultiple=bool, Inherited=bool)]
z destination - typ cíle, pro který je atribut použitelný.
z Lze povolit násobnou aplikaci.
z Povolit dědičnost atributu.
z Cíl atributu je dán výčtovým typem AttributeTargets.
z Assembly, Class, Constructor, Delegate, Enum, Event,
Field, Interface, Method, Parameter, Property,
RetrurnValue, Struct, All.
z Cíle lze kombinovat pomocí logického operátoru OR.
Programové konstrukce 171
Atributy – Atributy atributů (2)
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
AllowMultiple=true, Inherited=false)]
class MyAttribute : Attribute {
private string message;
public MyAttribute(string message) {
this.message=message;
}
int number;
public int Number {
get {return number;}
set {number=value;}
}
public string Message {
get {return this.message;}
}
}
[MyAttribute("Simple class",Number=1)]
[MyAttribute("but very nice!")]
class Example {}
Programové konstrukce 172
Spolupráce s existujícím
kódem
z Autoři platformy .NET a jazyka C# umožnili programátorům
použít stávající programy. Používáme-li takovéto programy,
zříkáme se výhod, které poskytuje CLR. Hovoříme pak o
neřízeném kódu.
z Spolupráce s komponentami modelu COM - schopnost
prostředí .NET používat komponenty modelu COM a naopak
komponentám modelu COM používat prvky prostředí .NET.
z Spolupráce s běžnými knihovnami DLL - tyto služby
umožňují programátorům v prostředí .NET používat
knihovny DLL.
z Nezabezpečený kód - umožňuje programátorům v jazyce C#
používat například ukazatele. Takto vytvořený program není
spravován CLR systému .NET.
Programové konstrukce 173
Spolupráce s existujícím kódem -
COM interoperability (2)
z Použití existující COM komponenty v .NET aplikaci.
z Nejprve je nutné COM komponentu registrovat v registry
(nástroj regsvr32.exe).
z Vytvoříme nový projekt v jazyce C#. V okně Solution
Explorer aplikace Visual Studio vybereme položku Add
Reference.
z Najdeme příslušnou COM komponentu.
z Reference na tuto komponentu byla přidána a lze ji
normálně používat (tedy instanciovat a pak volat její
metody,....).
z Řekněme, že máme zaregistrovánu COM komponentu
example.dll. Tato komponenta je přístupná přes rozhraní
IExample
Programové konstrukce 174
Spolupráce s existujícím kódem -
COM interoperability (2)
interface IExample
{
int getNumber();
}
z Reference na tuto komponentu pak bude: EXAMPLELib.Example.
class Test
{
public static void Main()
{
EXAMPLELib.Example example = new
EXAMPLELib.Example();
Console.WriteLine(example.getMessage());
}
}
Programové konstrukce 175
Spolupráce s existujícím kódem -
COM interoperability (3)
z Použití .NET komponenty na místo COM
komponenty.
z Vytvoříme nový C# projekt typu Class Library.
z Komponentu musíme zaregistrovat v Registry.
K tomu složí nástroj regasm.exe.
z Pro programy, které pracují s typovanými
knihovnami lze vygenerovat potřebny .tlb
soubor nástrojem tlbexp.exe
z Pak lze tuto komponentu využívat stejně jako
COM komponentu.
Programové konstrukce 176
Spolupráce s existujícím
kódem – DLL knihovny
z Platform Invocation Services (PInvoke) - tyto
služby umožňují řízenému kódu pracovat s
knihovnami a funkcemi exportovanými z
dynamických knihoven.
z Knihovna DLL je importovaná pomocí
atributu DllImport.
z Importované funkce musí být označeny jako
externí (klíčové slovo extern).
Programové konstrukce 177
Spolupráce s existujícím
kódem – DLL knihovny
z Následující příklad ukazuje volání metody MessageBox z knihovny
User32.dll.
using System;
using System.Runtime.InteropServices;
class RunApp
{
[DllImport("user32.dll")]
static extern int MessageBoxA(int hWnd, string
msg,string caption,int type);
static void Main(string[] args)
{
MessageBoxA(0,"Hello world!","C# is calling!",0);
}
}
Programové konstrukce 178
Spolupráce s existujícím
kódem – DLL knihovny
z Importovanou funkci lze pro použití v jazyce C# přejmenovat. Slouží k
tomu pojmenovaný parametr EntryPoint atributu DllImport.
using System;
using System.Runtime.InteropServices;
class RunApp
{
[DllImport("user32.dll", EntryPoint="MessageBox")]
static extern int NiceWindow(int hWnd, string
msg,string caption,int type);
static void Main(string[] args)
{
NiceWindow(0,"Hello world!","C# is calling!",0);
}
}
Programové konstrukce 179
Nezabezpečený kód (1)
z Používáme-li nebezpečný kód, explicitně se zříkáme vlastností CLR.
z Blok je definován pomocí klíčového slova unsafe a složenými závorkami.
z Klíčové slovo unsafe lze použít také jako modifikátor u metody případně tříd.
z Je nutné překladači povolit unsafe bloky (Project-Properties-Configuration Properties-Build-
Allow Unsafe Code Blocks).
class RunApp
{
public static unsafe void Swap(int *x, int*y)
{
int tmp=*x; *x=*y; *y=tmp;
}
static void Main(string[] args)
{
int a=1; int b=4;
unsafe
{
Swap(&a,&b);
}
Console.WriteLine("{0},{1}",a,b); //output: 4,1
}
}
Programové konstrukce 180
Nezabezpečený kód (2)
z Používáme-li přímý přístup do paměti, mohlo by dojít ke srážce s
algoritmem garbage collection.
z Klíčové slovo fixed je nástrojem určeným pro znehybnění kusu paměti.
fixed (type* pointer = expression) statement
unsafe class Class1 {
public static void Fill(int *array,int size) {
while(size-- > 0)*array++ = size+1;
}
public static void Main() {
int[] array=new int[10];
fixed(int* pointerToArray = array) {
Fill(pointerToArray,10);
}
foreach(int field in array) Console.WriteLine(field);
}
}
Vloženo: 23.04.2009
Velikost: 1003,50 kB
Komentáře
Tento materiál neobsahuje žádné komentáře.
Mohlo by tě zajímat:
Reference vyučujících předmětu 128PR2G - Programování 2Podobné materiály
- 122SPRO - Stavební procesy - Řízení výstavby - učebnice
- 122TPS - Technologie a provoz stavby - Řízení výstavby - učebnice
- 122TS1 - Technologie staveb L1 - Řízení výstavby - učebnice
- 122TS61 - Strategie dodavatele stavby - Řízení výstavby - učebnice
- 122XSDS - Strategie dodavatele stavby - Řízení výstavby - učebnice
Copyright 2025 unium.cz


