OPP: Properties (zB gets und sets) und Konstruktoren richtig deklarieren

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von BiedermannS.

    OPP: Properties (zB gets und sets) und Konstruktoren richtig deklarieren

    Hallo, Experte. bin neue hier.

    Seit paar Tagen versuche ich mein .NET wissen auffrischen. In vielen C# Bücher/Tutorials sieht man einen sehr häufigen OOP Beispiel - die Person Klasse
    In C# sieht die ungefähr so aus:

    Quellcode

    1. public class Person
    2. {
    3. public int Age {get; set;}
    4. public string FirstName {get; set;}
    5. public string LastName {get; set;}
    6. public Person(){}
    7. public Person(string firstName, string lastName, int age)
    8. {
    9. Age = age;
    10. FirstName = firstName;
    11. LastName = lastName;
    12. }
    13. public override string ToString()
    14. {
    15. return string.Format("Name: {0} {1}, Age: {2}", FirstName, LastName, Age);
    16. }
    17. }


    Dabei fallen mir sofort zwei Sachen auf:
    1. Deklaration von Eigenschaften(Properties) a lá public int Age {get; set;}
    2. Konstruktor wird zweimal definiert ? einmal public Person(){} und public Person(...params...){...code...}

    Natürlich wollte ich dieselbe Klasse in VB schreiben. Dabei bin ich auf verschieden Varianten gestoßen.

    Variante 1

    VB.NET-Quellcode

    1. Public Class Person
    2. Public Property Age() As Integer
    3. Public Property FirstName() As String
    4. Public Property LastName() As String
    5. Public Sub New()
    6. End Sub
    7. Public Sub New(ByVal firstName As String, ByVal lastName As String, ByVal age As Integer)
    8. Me.Age = age
    9. Me.FirstName = firstName
    10. Me.LastName = lastName
    11. End Sub
    12. Public Overrides Function ToString() As String
    13. Return String.Format("Name: {0} {1}, Age: {2}", FirstName, LastName, Age)
    14. End Function
    15. End Class


    Variante 1

    VB.NET-Quellcode

    1. Public Class Person
    2. Public Property Age() As Integer
    3. Public Property FirstName() As String
    4. Public Property LastName() As String
    5. Public Sub New()
    6. End Sub
    7. Public Sub New(ByVal firstName As String, ByVal lastName As String, ByVal age As Integer)
    8. Me.Age = age
    9. Me.FirstName = firstName
    10. Me.LastName = lastName
    11. End Sub
    12. Public Overrides Function ToString() As String
    13. Return String.Format("Name: {0} {1}, Age: {2}", FirstName, LastName, Age)
    14. End Function
    15. End Class


    Variante 2

    VB.NET-Quellcode

    1. Public Class Person
    2. Public Property Age() As Integer
    3. '
    4. ' Gets und Sets werden explizit deklariert
    5. '
    6. Get
    7. Return m_Age
    8. End Get
    9. Set
    10. m_Age = Value
    11. End Set
    12. End Property
    13. '
    14. ' Privete Eigenschaften werden verwendet
    15. '
    16. Private m_Age As Integer
    17. Public Property FirstName() As String
    18. Get
    19. Return m_FirstName
    20. End Get
    21. Set
    22. m_FirstName = Value
    23. End Set
    24. End Property
    25. Private m_FirstName As String
    26. Public Property LastName() As String
    27. Get
    28. Return m_LastName
    29. End Get
    30. Set
    31. m_LastName = Value
    32. End Set
    33. End Property
    34. Private m_LastName As String
    35. Public Sub New()
    36. End Sub
    37. Public Sub New(firstName As String, lastName As String, age As Integer)
    38. Age = age
    39. FirstName = firstName
    40. LastName = lastName
    41. End Sub
    42. Public Overrides Function ToString() As String
    43. Return String.Format("Name: {0} {1}, Age: {2}", FirstName, LastName, Age)
    44. End Function
    45. End Class


    Gibt es ein "unterschied" zwischen beiden Varianten (außer Quell-Code Länge) ? Wann mach es Sinn (falls überhaupt) die Proeprties ducrch Gets und Sets und Provate zu deklarieren?

    die zweite Frage ist: Wozu zwei Konstruktoren ?

    vLight schrieb:

    die zweite Frage ist: Wozu zwei Konstruktoren ?

    Du kannst die Klasse dadurch so deklarieren:

    C-Quellcode

    1. Person pers = new Person();


    und danach Eigenschaften setzen oder gleich:

    C-Quellcode

    1. Person pers = new Person("Hans", 20);


    Kann dann bei sowas vorteilhaft sein:

    C-Quellcode

    1. List<Person> Personal = new List<Person>();
    2. Personal.Add(new Person("Hans", 20));


    ..anstatt:

    C-Quellcode

    1. List<Person> Personal = new List<Person>();
    2. Person pers = new Person();
    3. pers.Name = "Hans";
    4. pers.Age = 20;
    5. Personal.Add(pers);


    Du kannst halt die Klasse dadurch anders Startwerte geben ;)
    Wann mach es Sinn (falls überhaupt) die Proeprties ducrch Gets und Sets und Provate zu deklarieren?


    Vorteile:
    ReadOnly, Attribute, Protected / Private Set, Bei Get / Set Funktionen aufrufen (z.b. einen anderen wert mit aktualieren / Counter).

    Gibts da sonst noch was?

    VB.NET-Quellcode

    1. Public Property Age() As Integer
    ist Syntax VB 2010

    VB.NET-Quellcode

    1. Public Property Age() As Integer
    2. Get
    3. Return m_Age
    4. End Get
    5. Set
    6. m_Age = Value
    7. End Set
    8. End Property
    ist Syntax älter als VB 2010
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    mehr möglichkeiten durch die Längere Version:

    Du kannst kontrollieren was "ein und aus" geht - ggf werte überprüfen (Fahrzeug.Länge darf nicht negativ sein, etc). Ebenso kannst du andere werte Updaten (Wenn Spieler.Health <= 0 dann ist'er wohl hopps gegangen) und ggf auch Events Raisen (siehe z.B. Trackbar: Wenn sich .Value ändert, dann wird das ValueChange-Event aufgerufen).

    Willst du nur eine Property haben, dann reicht auch der Einzeiler - afaik braucht ja z.b. das PropertyGrid Eigenschaften statt normaler Felder.

    vLight schrieb:

    Hehe
    Geh mal mit nem Refektor rein und wag ihm, dür welches Studio er decompilieren soll. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    ist Syntax VB 2010

    ist Syntax älter als VB 2010

    Das wäre mir aber neu...

    VB.NET-Quellcode

    1. Public Property Age() As Integer

    Gabs in VB2008 auch schon, wenn ich mich gerade nicht täusche.


    Zur eigentlichen Frage:
    Wenn eine Eigenschaft nur gesetzt und gelesen werden soll reicht es eine "auto implemented property" zu erstellen, also

    VB.NET-Quellcode

    1. Public Property Age() As Integer


    Wenn du volle Kontrolle über die Eigenschaft brauchst.
    z.B.: Wenn die Eigenschaft gesetzt wird, soll gleich eine zweite Eigenschaft mit gesetzt werden oder um eine Ober-/Untergrenze zu definieren oder wenn du Strings herausfiltern willst, die nicht erlaubt sind usw. bleibt dir nichts anderes übrig, als deine Eigenschaft selbst zu implementieren.

    Eigenschaften sind nichts anderes als Methoden um eine private Variable gezielt zur Verfügung zu stellen.
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D

    BiedermannS schrieb:

    Zur eigentlichen Frage:
    Ja, es genügt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    xtts02 schrieb:

    Doch, das tust Du!

    Stimmt. Ist auch schon wieder lang her.

    RodFromGermany schrieb:

    Ja, es genügt.

    Das versteh ich nicht. Was genügt?
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D

    BiedermannS schrieb:

    Was genügt?

    BiedermannS schrieb:

    Zur eigentlichen Frage:
    Wenn eine Eigenschaft nur gesetzt und gelesen werden soll reicht es eine "auto implemented property" zu erstellen, also

    VB.NET-Quellcode

    1. Public Property Age() As Integer

    RodFromGermany schrieb:

    Ja, es genügt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    petaod schrieb:

    Ich frag mich jetzt, wo der Unterschied zwischen einer AutoImplemented Property und einer Variablen ist
    Wenn Du eine Property in einer designer-anzeigbaren Klasse geberierst (UserControl), wird diese vom Designer mit angeboten.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    petaod schrieb:

    Ich frag mich jetzt, wo der Unterschied zwischen einer AutoImplemented Property und einer Variablen ist

    Properties besitzen immer einen Getter und einen Setter.

    Auf Variablen wird einfach zugegriffen.

    AutoImplemented sagt nur aus, dass Getter und Setter automatisch erstellt wird.
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D

    BiedermannS schrieb:

    Properties besitzen immer einen Getter und einen Setter.
    Fast immer:

    VB.NET-Quellcode

    1. Private _MyValue As Integer
    2. Public ReadOnly Property MyValue() As Integer
    3. Get
    4. Return _MyValue
    5. End Get
    6. End Property
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    BiedermannS schrieb:

    Properties besitzen immer einen Getter und einen Setter.


    Außer WriteOnly und ReadOnly, die besitzen nur entweder Setter oder Getter.

    :)
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D