Eine Frage in Bezug auf das ausgliedern einer Klasse in eine andere Datei

  • C#

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von loosm.

    Eine Frage in Bezug auf das ausgliedern einer Klasse in eine andere Datei

    Ich hatte ein kleines Programm geschrieben, weil es 2 Unterprogramme enthält, musste ich in dem Programm eine Klasse anlegen. Mir wurde in anderen Beiträgen bereits gesagt, dass ich die Klasse in eine andere Datei auslagern soll. Also habe ich im Menü Datei des Visual Studio “ Neu „ und dann „ Klasse in C#.“ ausgewählt. Das Visual Studio hat mir als Vorschlag für das Erstellen der Klasse in der neuen Datei den folgenden Code angezeigt.

    C#-Quellcode

    1. using System;
    2. public class Class1
    3. {
    4. public Class1()
    5. {
    6. }
    7. }


    von diesem Code habe ich nur das using System stehen lassen und den Rest durch den Code ersetzt, den ich im Hauptprogramm ausgeschnitten habe. Hier ist der Code der Datei class1.cs

    C#-Quellcode

    1. using System;
    2. public static class LokaleFunktionen
    3. {
    4. public static ulong Erg;
    5. public static ulong Fakultaet(int k)
    6. {
    7. if (k == 0)
    8. {
    9. return 1;
    10. }
    11. ulong Erg = 1;
    12. for (int i = 1; i <= k; i++)
    13. {
    14. Erg *= (ulong)i;
    15. }
    16. return Erg;
    17. }
    18. public static ulong Nueberk(int N, int k)
    19. {
    20. ulong Y, X, Nfak, Kfak;
    21. if (k == 0 & N >= 0)
    22. Y = 1;
    23. else
    24. {
    25. X = Fakultaet(N - k);
    26. Nfak = Fakultaet(N);
    27. Kfak = Fakultaet(k);
    28. Y = System.Convert.ToUInt64(Nfak / (double)(Kfak * X));
    29. }
    30. return Y;
    31. }


    Ich weis nicht ob der Code innerhalb der Datei class1.cs falsch eingefügt wurde.

    Ich habe versucht die Datei am Ort : Source / repos / Projektname / Projektname und eine Ebene höher in Source / repos / Projektname abzuspeichern damit ich sie benutzen kann. Die beiden Orte, die ich zum Speichern ausgewählt hatte, unterscheiden sich aber nicht in ihrer Wirkung. Die neue Datei class1.cs ist nicht im Projektmappen Explorer sichtbar, und wenn die Klasse im Hauptprogramm fehlt, wird ihr Code nicht durch das Dokument class1.cs ersetzt, welches den Code der Klasse enthält.

    Es könnte auch sein, dass ich damit das ganze funktioniert, zusätzlich im Hauptprogramm noch Code verändern müsste. RodFromGermany hat mir in dem Beitrag :Wie kann ich eine Funktion mit Rückgabewert in mein C# Programm integrieren ?
    Ein Codebeispiel gezeigt, von dem ich vermute, dass es sich um Code für das Hauptprogramm handelt. Ich verstehe von dem Thema leider so wenig, dass ich nicht weis wie ich das Beispiel an mein Programm anpassen könnte. Für den Fall, dass der Code im Hauptprogramm verändert werden muss, könnte mir jemand zeigen, wie der Code im Hauptprogramm nach dem Auslagern der Klasse in eine andere Datei verändert werden müsste, damit alles weiterhin funktioniert ?

    Hier ist der Code des Hauptprogramms.
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Data;
    5. using System.Drawing;
    6. using System.Linq;
    7. using System.Reflection.Emit;
    8. using
    9. System.Text;
    10. using System.Threading.Tasks;
    11. using System.Windows.Forms;
    12. namespace Binominal
    13. {
    14. public partial
    15. class Form1 : Form
    16. {
    17. public Form1()
    18. {
    19. InitializeComponent();
    20. }
    21. //An dieser Stelle hatte ich die Klasse ausgeschnitten die jetzt in der Datei class1.cs ist
    22. }
    23. private int N, i, R;
    24. private double P, var1, var2, var3, var4, Summe;
    25. private void button1_Click(object sender, EventArgs e)
    26. {
    27. {
    28. double[] ArrayB = new double[N + 1];
    29. double[]ArrayC = new double[N + 1];
    30. int K = 0;
    31. for (K = 0; K <= N; K++)
    32. {
    33. var2 = 1 - P;
    34. var3 = N - K;
    35. var1 = (double)Math.Pow(P, K);
    36. var4 = (double)Math.Pow(var2, var3);
    37. ArrayB[K] = LokaleFunktionen.Nueberk(N, K) * var1 * var4;
    38. Summe = Summe + ArrayB[K];
    39. ArrayC[K] = Summe;
    40. }
    41. {
    42. Ausg += " Fuer mindestens " + R.ToString() + " mal Erfolg liegt die Wahrscheinlichkeit bei : " + (1 - ArrayC[R - 1]).ToString()
    43. +
    44. Environment.NewLine;
    45. Ausg += " Fuer mehr als " + R.ToString() + " mal Erfolg liegt die Wahrscheinlichkeit bei : " + (1 - ArrayC[R]).ToString()
    46. +
    47. Environment.NewLine;
    48. Ausg += "
    49. Fuer hoechstens " + R.ToString() + " mal Erfolg liegt die Wahrscheinlichkeit bei : " + (ArrayC[R]).ToString()
    50. +
    51. Environment.NewLine;
    52. Ausg
    53. += "
    54. Fuer weniger als " + R.ToString() + " mal Erfolg liegt die Wahrscheinlichkeit bei : " + (ArrayC[R - 1]).ToString()
    55. +
    56. Environment.NewLine;
    57. Ausg += " Fuer genau "
    58. + R.ToString() + " mal Erfolg liegt die Wahrscheinlichkeit bei : " + (ArrayB[R]).ToString()
    59. +
    60. Environment.NewLine;
    61. }
    62. {
    63. label4.Text = Ausg;
    64. }
    65. {
    66. System.Object[] ItemObject = new System.Object[N + 1];
    67. for (int i = 0; i <= N; i++)
    68. {
    69. ItemObject[i]= " Die Wahrscheinlichkeit genau " + i +" mal Erfolg zu haben beträgt: " + ArrayB[i];
    70. }
    71. listBox1.Items.AddRange(ItemObject);
    72. }
    73. {
    74. System.Object[] ItemObject = new System.Object[N + 1];
    75. for (int i = 0; i <= N; i++)
    76. {
    77. ItemObject[i] = " K : " + i + " kumuliert : " + ArrayC[i];
    78. }
    79. listBox2.Items.AddRange(ItemObject);
    80. }
    81. }
    82. }
    83. private string Ausg;
    84. private void Form1_Load(object sender, EventArgs e)
    85. {
    86. {
    87. label4.Text = "Ein Rechner für die Binomialverteilung";
    88. label1.Text= @"
    89. Hier das N eingeben
    90. N= Anzahl der Versuche";
    91. label2.Text = @"Hier
    92. das P eingeben
    93. P = prozentuale Wahrscheinlichkeit
    94. als Zahl zwischen 0 und 1 ";
    95. label3.Text = @"Hier das K eingeben
    96. K
    97. = die gesuchte Anzahl
    98. der
    99. Treffer";
    100. button1.Text = " Start";
    101. }
    102. }
    103. private void textBox1_TextChanged(object sender, EventArgs e)
    104. {
    105. {
    106. bool Erfolg = Int32.TryParse(textBox1.Text, out int tbInt);
    107. if (Erfolg)
    108. {
    109. N = tbInt;
    110. }
    111. else
    112. {
    113. label4.Text = " Es wurde keine Zahl eingegeben ";
    114. }
    115. }
    116. }
    117. privatevoid textBox2_TextChanged(object sender, EventArgs e)
    118. {
    119. {
    120. P = double.Parse(textBox2.Text);
    121. }
    122. }
    123. private void textBox3_TextChanged(object sender, EventArgs e)
    124. {
    125. {
    126. bool Erfolg = Int32.TryParse(textBox3.Text, out int tbInt);
    127. if (Erfolg)
    128. {
    129. R = tbInt;
    130. }
    131. else
    132. {
    133. label4.Text = " Es wurde keine Zahl eingegeben ";
    134. }
    135. }
    136. }
    137. }
    138. }



    aufgrund des Datenumfangs Spoiler hinzugefügt und CodeTags korrigiert; bitte zukünftig darauf achten, das richtige CodeHighlighting zu verwenden ~VaporiZed[/b]

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    hmm - in welchem Namespace ist denn deine Klassse LokaleFunktionen?
    Weil wenn man sie ansprechen will, muss man den namespace entweder direkt angeben (vollqualifizierter Name) oder indirekt, indem man den Namespace per using-Direktive einbindet.

    achso - in welchem namespace war sie denn, bevor du sie ausgeschnitten hattest?
    Dann dafür sorgen, dass sie auch in ihrer neuen Datei demselben Namespace angehört.
    @loosm Beschreibe mal ohne Verwendung von Code, was Du eigentlich vorhast.
    Wenn Du eine Klasse auf mehrere Dateien verteilen willst, muss der Code im selben Namespace und in der selben Klasse sein, die Klasse ist dann in beiden Dateien mit partial zu deklarieren.
    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!

    loosm schrieb:

    klettert die Fehleranzahl von 0 auf 69
    Das macht ja erstmal Sinn wenn eine Klasse fehlt, auf die zugegriffen wird.

    loosm schrieb:

    unter das using System noch namespace Binominal zu schreiben
    Heißt dein Hauptprogramm auch Binominal? Denn dann nützt es nichts da einen gleichlautenden Namespace drumrum zu basteln, das ist dann ein Namespace im Namespace:

    Dann muss die Ursache geklärt werden warum deine neu hinzugefügte Klasse nicht von vornherein im richtigen Namespace landet. Vielleicht eine c# Besonderheit?

    loosm schrieb:

    ich habe eben versucht noch namespace Binominal zu schreiben. ...
    Jo, ich glaub, du weisst noch garnet, was ein Namespace ist, und was partial bedeutet etc. Und in diesem Fall kommt beides zusammen: Die ausgelagerte Datei muss in dieselbe partiale Klasse - welche natürlich nur im selben Namespace möglich ist. Also probierma in der neuen Datei:

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. namespace Binominal {
    5. public partial class Form1 {
    6. public static class LokaleFunktionen {
    7. public static ulong Erg;
    8. public static ulong Fakultaet(int k) {
    9. if (k == 0) {
    10. return 1;
    11. }
    12. ulong Erg = 1;
    13. for (int i = 1; i <= k; i++) {
    14. Erg *= (ulong)i;
    15. }
    16. return Erg;
    17. }
    18. public static ulong Nueberk(int N, int k) {
    19. ulong Y, X, Nfak, Kfak;
    20. if (k == 0 & N >= 0)
    21. Y = 1;
    22. else {
    23. X = Fakultaet(N - k);
    24. Nfak = Fakultaet(N);
    25. Kfak = Fakultaet(k);
    26. Y = System.Convert.ToUInt64(Nfak / (double)(Kfak * X));
    27. }
    28. return Y;
    29. }
    30. }
    31. }
    32. }
    natürlich ungetestet - ich hab ja nicht dein Form1

    Ich würde dir auch dieses kompakte Layout ans Herz legen, weil man versteht eine Klasse besser, wenn sie komplett auf einen Bildschirm passt, ohne dass man herumscrollen muss.
    Man kann das im VisualStudio so einstellen,
    Wenn ich die Änderungen die mir ErfinderDesRades vorgeschlagen hat in der Datei class1.cs am am Ort : Source / repos /Binominal /Binominal abspeichere wird sie mir trotzdem nicht im Hauptprogramm im Projektmappen Explorer angezeigt. Was habe ich vor : der Grund weshalb ich versuchen wollte die Klasse in eine eigene Datei auszulagern ist, das in dem Beitrag : Wie kann ich in C# Variablen erstellen?
    Dksksm geschrieben hat: Da passt einiges nicht. Eine Klasse die "global" funktionieren soll gehört nicht in die Form-Klasse, sondern als separate Klasse, ab besten sogar in einem eigenen Namespace in einer eigenen Datei.
    Zumindest das mit der eigenen Datei wollte ich gerne hin bekommen. Ich frage mich aber ob das bezogen auf mein Programm überhaupt möglich ist, weil wenn RodFromGermany mir schreibt :Wenn Du eine Klasse auf mehrere Dateien verteilen willst, muss der Code im selben Namespace und in der selben Klasse sein, die Klasse ist dann in beiden Dateien mit partial zu deklarieren.
    Kann es dann sein, das es gar nicht möglich ist, dass die Klasse im Hauptprogramm verschwindet, weil ich ja in der einzigen Befehlszeile, in der ich die Klasse benutze :

    C#-Quellcode

    1. ArrayB[K] = LokaleFunktionen.Nueberk(N, K) * var1 * var4;
    das Wort Partial nicht verwenden kann ?

    Eigentlich funktioniert das Programm ja mit der Klasse, die nur im Hauptprogramm steht. Ich weis nicht, ob ich die Klasse nochmal in einem anderen Programm
    benutzen will. Von daher wäre der einzige Sinn dieses Auslagerns, dass ich verstehe, wie es funktioniert. Sollte ich von daher das Auslagern einer Datei lieber dann nochmal probieren, wenn ich
    wirklich vorhabe eine Klasse in 2 verschiedenen Programmen zu verwenden ?

    loosm schrieb:

    das Wort Partial nicht verwenden kann
    Sieh Dir eine Form-Klasse an.
    Der Designer-Teil einer solchen Klasse ist in der Datei FormX.Designer.cs enthalten.
    Öffne mal die Dateien FormX.cs und FormX.Designer.cs nebeneinander, sieh Dir die Klassen-Deklarationen an, um das Konzept zu verstehen.
    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!

    loosm schrieb:

    Mir wurde in anderen Beiträgen bereits gesagt, dass ich die Klasse in eine andere Datei auslagern soll. Also habe ich im Menü Datei des Visual Studio “ Neu „ und dann „ Klasse in C#.“ ausgewählt
    Ich glaube, das ist gar nicht das, was du erreichen willst.
    Füge statt dessen im Project Explorer in deinem bestehenden Projekt eine neue C#-Klasse ein, wo du den Code einträgst.
    Rechter Mausklick auf dein Projekt .. Hinzufügen .. Klasse
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Durch den rechten Mausklick auf das Projekt .. Hinzufügen .. Klasse hat jetzt dazu geführt, dass die Datei Class1.cs am Ort : Source / repos /Binominal /Binominal auch im Projektmappen Explorer angezeigt wird. Den Code meiner Klasse : Lokale Funktionen kann ich aus dem Hauptprogramm trotzdem noch nicht ohne das Entstehen von Fehlermeldungen entfernen.
    In der Datei Form1.cs steht am Anfang unter namespace Binomial

    C#-Quellcode

    1. public partial class Form1 : Form
    2. {
    3. public Form1()
    4. {
    5. InitializeComponent();
    6. }


    In der Datei Form1.Designer.cs steht am Anfang unter namespace Binomial :

    C#-Quellcode

    1. partial class Form1
    2. {


    Ich vermute das dies bezogen auf meine Klasse : Lokale Funktionen bedeutet dass in der Datei Form1.cs

    C#-Quellcode

    1. public partial class LokaleFunktionen
    stehen bleiben muss. Aber wie genau ? Es macht ja keinen Sinn zu schreiben :

    C#-Quellcode

    1. public partial class LokaleFunktionen
    2. {
    um dann den Inhalt der sich schon in der Datei Class1.cs am Ort : Source / repos /Binominal /Binominal befindet nochmal aufzulisten.

    loosm schrieb:

    Es macht ja keinen Sinn zu schreiben :

    VB.NET-Quellcode

    1. public partial class LokaleFunktionen
    und

    VB.NET-Quellcode

    1. private partial class LokaleFunktionen
    :!:
    Das eine ist eine partial class LokaleFunktionen, das andere erhält alle erforderlichen Attribute (z.B. BaseClass, Interfaces usw).
    Ich verstehe immer noch nicht, was eigentlich Dein Problem ist, weil Du Dich mit Symptomen befasst, nicht mit Ursachen.
    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!
    Vergiss erstmal Partial, das brauchst du nur wenn du 1 Klasse an 2+ verschiedenen Orten schreibst. (Also für die Form1 Klasse, nicht für LokaleFunktionen)

    Du willst diese Klasse ja kompletto verschieben.

    In dem Zustand in dem dein Programm funktioniert, mach mal ein Bild im Objektexplorer von deinem Projekt.
    Ich vermute da sind mehr Namespaces als da eigentlich sein sollten.

    Haudruferzappeltnoch schrieb:

    2+ verschiedenen Orten
    => in 2+ verschiedene Dateien im selben Verzeichnis
    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!
    Wenn ich die Klasse unverändert im Hauptprogramm stehen lassen würde, macht es keinen Sinn die Datei Datei Class1.cs, welche sich am Ort :
    Source / repos /Binominal /Binominal befindet, ebenfalls stehen zu lassen. Das wäre ja nur eine unnötige doppelte Auflistung von Code.
    Es geht darum, dass ich nicht weis wie ich die Klasse aus der externen Datei, im Hauptprogramm benutzen kann.
    Wenn ich mir versuche vorzustellen, wie der Code, an mein Programm angepasst werden müsste, den mir RodFromGermany in
    dem Beitrag : Wie kann ich eine Funktion mit Rückgabewert in mein C# Programm integrieren ?
    in Bezug auf das Einbinden einer Datei mit einer neu erstellten Klasse gezeigt hat, denke ich, das macht keinen Sinn, weil meine Funktionen vom Typ Static sind und es sich auch nicht um Void Funktionen handelt. Kann es sein, dass das Auslagern einer Klasse in eine externe Datei nur dann Sinn macht, wenn man wirklich mit Objekten arbeitet. Und deshalb bei meinem kleinen Programm keinen Sinn macht ?

    loosm schrieb:

    Wenn ich die Änderungen die mir ErfinderDesRades vorgeschlagen hat in der Datei class1.cs am am Ort : Source / repos /Binominal /Binominal abspeichere wird sie mir trotzdem nicht im Hauptprogramm im Projektmappen Explorer angezeigt.
    Also wenn man einem Projekt eine Datei zufügt, dann wird die auch im Projektmappen Explorer angezeigt.
    Wie du das anders hingekriegt hast, ist mir schleierhaft - programmierst du mit Notepad?
    Ich weis auch nicht, warum es nur möglich war, dass ich mit dem rechten Mausklick auf das Projekt .. Hinzufügen .. Klasse im Projekt Explorer die Datei dadurch sichtbar machen konnte. Wenn es wirklich sinnvoll ist, die Klasse in eine externe Datei zu verschieben, müsste jemand mir zeigen wie ich den Code im Hauptprogramm verändern müsste um die ausgelagerte Klasse benutzen zu können. Bis jetzt funktioniert mein Programm nur dann, wenn die Klasse ungekürzt im Hauptprogramm steht.