Autor Beitrag
OldCat
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77

Win 10 Pro x64
C# (VS 2019), (VS 2022)
BeitragVerfasst: Sa 06.11.21 13:27 
Liebe Gemeinschaft,

heute frage ich mich, ob Werte für Felder einer Klasse lieber direkt definiert werden sollten, oder ob es doch besser ist, die Werte der Felder erst im Konstruktor zu definieren?

Habe hier mal jene Klasse, um die es geht, aus meinem tutorialbasierten Projekt gepostet. Achtung: Folgendes wird in diesem Code noch nicht angewendet: Arrays, Lists, Iterationen/Loops.

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
//using System.Text;
//using static System.Console;

namespace ItemShop
{
    class Shop
    {
        private string GameTitle; // = "=== Item Shop ===";
        private string Description; // = "Welcome to our shop!\nYou can chose between three different items:";
        private decimal OrderTotal; // = 0;

        public Shop()
        {
            System.Console.SetWindowSize(width: 75, height: 25);
            GameTitle = "=== Item Shop ===";
            Description = "Welcome to our shop!\nYou can chose between three different items:";
            OrderTotal = 0;
    }

        public void Run()
        {
            DisplayIntro();
            System.Console.WriteLine();
            SellItem("\"Chopped Sword\""19.99M);
            SellItem("\"Short Sword\""99.99M);
            SellItem("\"Long Sword\""199.99M);

            DisplayOutro();
        }

        private void DisplayIntro()
        {
            System.Console.Title = GameTitle;
            System.Console.WriteLine("=================");
            System.Console.WriteLine(GameTitle);
            System.Console.WriteLine("=================\n");
            System.Console.WriteLine(Description);
        }

        private void SellItem(string itemName, decimal cost)
        {
            System.Console.OutputEncoding = System.Text.Encoding.UTF8;
            // TODO: try - catch, to eliminate format exception at string response?
            System.Console.WriteLine($"Would you like to buy a(n) {itemName} for {cost:C2}? (y/n)");
            string response = System.Console.ReadLine().Trim().ToLower();
            if (response.StartsWith('y'))
            {
                System.Console.WriteLine("How many do you like?");
                string numberResponse = System.Console.ReadLine();
                try
                {
                    int quantity = System.Convert.ToInt32(numberResponse);

                    decimal itemTotal = cost * quantity;
                    System.Console.WriteLine($"You bought {quantity}x of {itemName} for {itemTotal:C2}.");
                }
                catch (System.FormatException)
                {
                    System.Console.WriteLine("This was invalid. Try to type in a number.");
                    SellItem(itemName, cost);
                }
                catch (System.OverflowException)
                {
                    System.Console.WriteLine("This was a too high or too low number. Try to type in a more realistic one...");
                    SellItem(itemName, cost);
                }
            }
            else
            {
                System.Console.WriteLine($"Oh well, you didn't buy a(n) {itemName}.");
            }
        }

        // TODO: DisplayOrderTotal()
        private void DisplayOrderTotal()
        {
        }

        private void DisplayOutro()
        {
            System.Console.WriteLine("Thanks for shopping.");
            System.Console.WriteLine("\nPress any key to exit...");
            System.Console.ReadKey();
        }
    }
}


Liebe Grüße
OldCat :wink2:

Moderiert von user profile iconTh69: Topic aus Sonstiges (.NET) verschoben am Sa 06.11.2021 um 17:20
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 06.11.21 13:57 
Vorweg macht oft keinen Unterschied. Technisch ist es am Ende das gleiche.

Tendenziell würde ich es bei Literalen/Konstanten nicht so machen wie du sondern eher direkt am Feld machen und nicht im Konstruktor.
Das hat das potential bei später möglichen Änderungen am längsten zu überleben.

Je nach Sinn der Felder solltest du dir eher überlegen ob es nicht eher Konstanten (const) sind oder zumindest readonly Felder. Für mich sehen zumindest GameTitle/Description nicht nach was aus was sich zur Laufzeit noch mal ändern sollte.

Für diesen Beitrag haben gedankt: OldCat
OldCat Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77

Win 10 Pro x64
C# (VS 2019), (VS 2022)
BeitragVerfasst: Sa 06.11.21 14:05 
Ah, ich danke Dir sehr für Deine Hilfe. :zustimm:

Du hast mir tatsächlich alle Fragen zum Thema beantworten können.

Anfangs hatte ich die Werte tatsächllich direkt am Feld definiert. Ja, die Werte der Felder werden sich zur Laufzeit in der Tat nicht mehr ändern. Werde mal nach readonly und Konstanten schauen (hab diesbezüglich noch nicht den Plan). Werde es dann aber so machen, dass die Felder readonly und/oder Konstanten sein werden.

Danke und liebe Grüße
OldCat :beer:
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 06.11.21 14:13 
Zitat:
Werde es dann aber so machen, dass die Felder readonly und/oder Konstanten sein werden


Ich verrate mal es wird "oder" sein ;)
OldCat Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77

Win 10 Pro x64
C# (VS 2019), (VS 2022)
BeitragVerfasst: Sa 06.11.21 14:20 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Ich verrate mal es wird "oder" sein ;)

Ja, hab es jetzt als konstante Felder angelegt. :zustimm:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
//using System.Text;
//using static System.Console;

namespace ItemShop
{
    class Shop
    {
        // Fields that won't change their values anymore, should be better coded as a constant field.
        const string GameTitle = "=== Item Shop ===";
        const string Description = "Welcome to our shop!\nYou can chose between three different items:";
        private decimal OrderTotal = 0;

        {
          ....
        }
    }
}


Moderiert von user profile iconTh69: Zitat korrigiert.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 06.11.21 14:50 
Ich würde dir noch empfehlen die Sichtbarkeiten dranzuschreiben.

Ja es gibt da defaults mit denen man arbeitet wenn man nichts hinschreibt aber ist dir bewusst das jetzt deine Shop Klasse internal ist und deine beiden Konstanten private?
Ich programmiere jetzt seit fast 40 Jahren und habe da selbst keinerlei Sicherheit wie bei den verschiedenen Kombinationsmöglichkeiten die Sichtbarkeit am Ende jetzt genau ist. Darum besser gleich hinschreiben.

Macht für dich und was du im Moment tust sicher keinen großen Unterschied. Sich das anzugewöhnen explizite Sichtbarkeiten zu benutzen hilft dir aber später und tut jetzt nicht weh.

Für diesen Beitrag haben gedankt: OldCat
OldCat Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77

Win 10 Pro x64
C# (VS 2019), (VS 2022)
BeitragVerfasst: Sa 06.11.21 15:30 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Ich würde dir noch empfehlen die Sichtbarkeiten dranzuschreiben.

Meinst Du so?

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
//using System.Text;
//using static System.Console;

namespace ItemShop
{
    internal class Shop
    {
        // Fields that won't change their values anymore, should be better coded as a constant field.
        private const string GameTitle = "=== Item Shop ===";
        private const string Description = "Welcome to our shop!\nYou can chose between three different items:";
        private decimal OrderTotal = 0.0M;
    }

    {
       ...
    }
}


Ja, das die Klasse jetzt nur noch im selben Projekt anwendbar ist, und die Konstanten nicht mehr außerhalb dieser Klasse wirksam sind, war mir tatsächlich nicht klar ... danke für den Tipp!
Ja, in der Tat ist es hier in diesem Projekt nicht weiter wild, dass dem so ist. Es bsteht nur aus der Shop-Klasse und der Program-Klasse mit Main()...

40 Jahre programmieren ist ne Hausnummer ...! Bin selbst 41 und habe erst vor ein paar Monaten langsam angefangen ... ^_^ Mal schauen, wohin die Reise mich führt... :lupe:


Zuletzt bearbeitet von OldCat am So 07.11.21 11:42, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 06.11.21 16:08 
So hab ich mir das vorgestellt ja.
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 06.11.21 18:34 
Ich würde auch immer internal bzw. private gegenüber public bevorzugen - außer man braucht explizit public.
Hauptsächlich, um direkt zu steuern, wo man was "sehen" kann, welche Klasse bzw. was davon genutzt werden darf und so weiter.
Bei mehreren Projekten (bzw. ein Projekt aufgeteilt) erreichst Du auf diese Weise eine Abschottung der einzelnen Komponenten, die eine gewisse Sicherheit bieten kann.

Für diesen Beitrag haben gedankt: OldCat