Laden...

Übergabe einer Klasse an ein WinForm

Letzter Beitrag vor 13 Tagen 8 Posts 271 Views
Übergabe einer Klasse an ein WinForm

Hi zusammen, Sorry, bin Anfängerin - ist also vielleicht eine doofe Frage:

Ich habe eine "Datenklasse", in der ich div. Daten "lagern" möchte. Diese Klasse wird in der Form1 instanziiert (muss sein). Jetzt möchte ich weitere Daten eingeben, die dieser Datenklasse übergeben werden sollen. Das möchte ich in einer Form2 machen. Ich würde nun gerne diese Datenklasse als ref. der Form2 übergeben, damit die dort ausgefüllt werden kann. Ich lege also eine Instanz von Datenklasse in Form2 an, und erstelle eine Methode, in der die Referenz der Instanz in Form2 übergeben wird. Leider kann ich diese Methode nicht public machen, nur private. Wie krieg ich denn diese Datenklasse als ref in die Form2? Wäre für einen Tipp sehr dankbar.

LG an euch alle. Rieke

(Die Fehlermeldung lautet:  CS0122    'Der Zugriff auf ... ist aufgrund des Schutzgrads nicht möglich. )

Hallo und willkommen,

was genau meinst du mit

Leider kann ich diese Methode nicht public machen, nur private.

?

Du brauchst nur das Schlüsselwort public vor die Methode schreiben (bzw. anstatt private).

Und bzgl.

Wie krieg ich denn diese Datenklasse als ref in die Form2?

Eine Klasse (im Gegensatz zu einer Struktur) wird automatisch als Referenz übergeben, d.h. bei z.B.

private MyData myData;

public void SetData(MyData data)
{
  myData = data;
}

beziehen sich alle Änderungen an den Eigenschaften von myData automatisch auch an den beim Aufruf übergebenen Parameter (aus der anderen Form-Klasse).

Üblicherweise würde man diese Referenz jedoch direkt im Konstruktor der Klasse übergeben (damit nicht noch extra eine weitere Methode bzw. Eigenschaft dafür aufgerufen werden muß):

public Form2(MyData data) // bzw. wie auch immer die Formklasse heißt
{
  myData = data;
}

PS:
Du kannst dir auch mal meinen Artikel zur "Kommunikation von 2 Forms" aus meiner Signatur dazu durchlesen.
Insb. wenn du die Form2als modalen Dialog mittels ShowDialog()aufrufst, kannst du den Code anders schreiben.

Hi TH69,

Vielen Dank für deine ausführliche Antwort und ja, so wie du das geschildert hast, dachte ich mirs ja auch. Leider kommt beim Verwenden von public statt private immer die Fehlermeldung

CS0051 (Inkonsistenter Zugriff: Parametertyp "myData" ist weniger zugreifbar als Methode

(Übergabemethode, die public ist))

DAs passiert auch, wenn ich den Konstruktor verwende.

Ich versuche folgendes:

(Form1)

Datenklasse dk = new Datenklasse()  //ist implizit private, hab ich mir sagen lassen.
Form2.getDatenKlasse(dk);                  //so weit so gut

(Form2)

Datenklasse dkForm2 = new Datenklasse()
public void getDatenklasse(Datenklasse dk) // Fehlermeldung CS0051 - würde ich diese Methode private machen, wäre alles ok - aber natürlich nutzlos.
{
    dkForm2=dk;
}

PS: Sorry, die Fehlermeldungsbez. des ersten Beitrags war falsch - da bin ich wohl eine Zeile zu weit nach unten gerutscht. Es ist CS0051, nicht CS0122

Hi, zunächst die Bitte Deinen Code in Zukunft in die Code Tags zu setzen, das ist echt nicht so schwer und erleichtert allen das Lesen.


Zu allen CS Fehlern gibt es einen Dokueintrag, der zeigt, wodurch der Fehler ausgelöst wird, in Deinem Fall eben CS0051.

// CS0051.cs
public class A
{
    // Try making B public since F is public
    // B is implicitly private here.
    class B
    {
    }

    public static void F(B b)  // CS0051
    {
    }

    public static void Main()
    {
    }
}

Wie Du hier auch am Kommentar siehst, wird am Konstruktor von "F" der Parameter "B" erwartet.
"B" ist aber eine private Sub-Klasse von A, und kann daher nicht als Public-Parameter verwendet werden.

Bei Dir wird das der gleiche oder ein ähnlicher Fall sein. Ich rate mal, weil Du den Code nicht zeigst: Deine Klasse Datenklasse ist private, aber ein Parameter einer Public-Methode einer Public-Klasse - das geht nicht.


Ansonsten beachte die Hinweise von Th69:

Das bedeutet, daß auch deine Datenklasse public sein muß:

public class Datenklasse
{
  // ...
}

Alternativ könnte man auch beide auf internal setzen (welches der Standard bei Klassen ist, wenn man selber keinen Zugriffsmodifikator angibt) - dies wäre aber nur bei Libraries sinnvoll, um den Zugriff einzuschränken.

PS:
Warum heißt deine Methode getDatenklasse anstatt setDatenklasse(bzw. laut C# Styleguide besser SetDatenklasse)?

Oh mein Gott, endlich gelöst. Vielen Dank. Der Scheiß mit dem Internal wars und public löst das Problem - wofür auch immer dieses "internal" gut ist???

Vielen Dank - ich hab schon überlegt, aus dem Fenster zu springen. Jetzt kann ich doch weitermachen.

LG

Rieke.

Zitat von RiekeSeidl66

wofür auch immer dieses "internal" gut ist???

Weil es genug Situationen gibt, wo internal offensichtlich unabdingbar ist...

  • man hat internes Zeug, was man nicht aktiv nach Außen geben möchte, aber trotzdem eine Testbarkeit haben will/muss, siehe InternalsVisibleTo
  • weil man Zeug nur innerhalb einer Assembly zugreifbar haben will (klassische "Assembly Helfer Klassen" zB)
  • je größer das Projekt und desto mehr Devs das Projekt nutzen, desto nützlicher ist i.d.R. internal
  • bei Tools wie Obfuscation (wenn man es nutzen will) werden public-Elemente nicht obfuscated, private und internal schon, da dies dann sicher ist

.. und dutzende weitere nützliche Fälle von internal. Feel free to google 😉

  • Wer lesen kann, ist klar im Vorteil
  • Meistens sitzt der Fehler vorm Monitor
  • "Geht nicht" ist keine Fehlermeldung!
  • "Ich kann programmieren" != "Ich habe den Code bei Google gefunden"

GidF