Catz skrev:
Är det vettigt att använda sig av transactions för att behålla konsistens på datan i databasen eller ska man försöka programmera runt alla problem som kan dyka upp?
Transaction skall du använda dig av när du vill att ALLT eller INGET skall genomföras. Alltså om du skall göra fem INSERT statement mot din databas eller 5 olika databaser för den delen, och så vill du vara säker på att ALLA 5 skall sättas in eller ingen. Det är inget som du försöka programmera runt på egen hand, utan använda de funktioner som finns. Visst kan du lösa det på egen hand, men jag skulle definitivt inte råda det till dig, det kan lätt bli väldigt komplicerat.
Catz skrev:
Jag vet vad det är för skillnad på protected, private och public på en class men har inte förstått vad jag ska använda det till egentligen.... Antar att det är för att jag inte är så noga när jag deklarerar mina variabler. Hur ska man göra här egentligen
Det är ganska självbeskrivande, tja kanske inte protected eller Internal. Men Private är som den beskriver privat för min egen klass. Det betyder att det är endast inne ifrån klassen som man kan komma åt denna metod, vilket är väldigt behändigt när du delar upp någon sorts logik i flera metoder för att återanvända dem, eller för att underlätta kodförståelsen. Det är ju inget som du vill att användaren av din klass skall se. För att ta ett exempel, så tar vi bilklassen.
På denna klass har du en metod (publik) GörOmKörning() som kan anropas för alla som har en instans av din klass (alltså de har en bil). Men när du menar GörOmKörning() så menar du egentligen:
1. TittaBakåt();
2. TittaDödaVinklen();
3. SättPåBlinkers();
4. BytFil();
5. GasaSomFan();
6. KontrolleraSåDuPasseratBilen();
7. TittaDödaVinklen();
8. BytFil();
9. StängAvBlinkers();
osv osv... Detta (och säkert mer) skall göras när du skall göra en omkörning, men du vill ju inte att föraren skall behöva vet allt detta, utan han skall bara behöva bestämma att det är dags för en omkörning och sedan fixar din omkörningsmetod allt det andra "under skalet". Det är så du använder private/public. Public till allt som du vill exponera från din klass, och private för allt som du inte vill att någon annan skall känna till.
Protected fungerar som ett mellanting mellan public och private så till vida att den är private för att som har en instans av ditt objekt, men public för alla klasser som ärver från ditt objekt.
Så i vårt bil förhållande så hade vi gjort så att istället för att ha alla de 9 metoderna private så kan vi sätta dem till protected, du kan man fortfarande inte se dem om du har en instans av klassen bil, du ser fortfarande bara GörOmKörnings() metoden. Men om vi nu skapar en SportBil{} klass och ärver från vår Bil{} klass, så fungerar dessa 0 metoder nu som privata metoder i bilen SportBil{} och vi kan göra en ny GörOmKörningsSportBil() metod (eller ännu bättre använa override och virtual på de olika metoderna, mer om det senare) och i denna metod, så struntar vi att använd blinkers och vi får då en "snabbare" omkörning ;)
Internal fungera så att den är public i samma assembly, men privat för alla utan för assemblyn. Alltså en klass som är Internal i en assembly kan bara anropas från klasser i detta assemblyt och inte från klasser i ett annat assembly.
Nu kommer det roliga. Abstracta och Virtuella metoder, här kan man nu börja se fördelarna med oo-programmering, då vi kan få 2 helt olika flöden på "samma metod" i olika klasser.
Säg att vi skapar klassen bil, och gör en metod som heter GörOmKörning() men vi gör den virtuell.
public Virtual bool GörOmKörning()
{
TittaBakåt();
TittaDödaVinklen();
SättPåBlinkers();
BytFil();
GasaSomFan();
KontrolleraSåDuPasseratBilen();
TittaDödaVinklen();
BytFil();
StängAvBlinkers();
}
Vad vi nu har har sagt här är att denna klass har en metod som heter GörOmKörning() men klasser som ärver från denna klass får lov överrida denna metod med sin egen kod.
Så i klassen SportBil{} som kan vi ha en liknande metod.
public class SportBil : Bil{
public override bool GörOmKörning()
{
TittaBakåt();
TittaDödaVinklen();
BytFil();
GasaSomFan();
KontrolleraSåDuPasseratBilen();
TittaDödaVinklen();
BytFil();
}
}
Här har vi nu 2 olika metoder men med samma namn, och varför är det så himla bra då? Kunde vi inte bara döpt den till GörOmKöring2() och så anropt den metoden istället. Ja visst kunde du ha gjort det, men med denna lösning så behöver du faktiskt inte vet vilken typ du bil är, säg att du har en lista som tar typen bil
List<Bil> bilList = new List<Bil>();
Denna lista kan nu innehålla både bil och SportBil.
bilList.Add(new Bil());
bilList.Add(new SportBil() as Bil);
om jag nu då vill göra en omkörning på alla mina bilar i listan så skulle man ju kunna göra så här:
foreach(Bil bil in bilList)
{
if(bil.GetType() == typeOf(SportBil))
((SportBil)bil).GörOmKörning2();
if(bil.GetTYpe() == typeOf(Bil))
bil.GörOmKörning();
}
Men hur snyggt är det och framför allt hur praktiskt är det, det kan ju faktiskt komma någon som skapar en LastBil som ärver från din Bil och lägger med den i listan, då kommer den aldrig att göra någon omkörning eftersom det alternativet inte finns med.
Men om vi istället har löst det så som vi har gjort med Virtual och override, så löser vi det så här.
foreach(Bil bil in bilList)
bil.GörOmKörning();
Och korrekt metod kommer att anropas för respektive typ. Och om någon skulle göra en LastBil, och inte överrida vår GörOmKörning() så kommer bastypens (alltså Bil) metod att anropas och en omkörningkommer att göras om än kanske inte helt så optimalt som det önskas....
Det är bara att sätta igång och leka, sätt en massa breakpoints i de olika metoderna så ser du hur rätt metod kommer att användas...
- M