Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Klasse ohne direkten Namen erstellen
Maggie123
myCSharp.de - Member



Dabei seit:
Beiträge: 4

Themenstarter:

Klasse ohne direkten Namen erstellen

beantworten | zitieren | melden

Hallo,
ich arbeite noch nicht lange mit C# und stehe vor folgendem Problem:

Während der Laufzeit sollen neue Klassen erstellt werden. Da ich nicht weiß wieviele es werden, kann ich diese aber nicht genau benennen.

Habe jetzt schon ziemlich lange im Internet gegoogelt, aber noch keine Lösung für das Problem gefunden.
Mein Denkansatz war, eine String Variable zu erzeugen, welche einen Namen für die Klasse erzeugt. Jedoch weiß ich jetzt nicht, wie ich die Klasse mithilfe der Variablen erstellen kann.
Bisheriger Programmcode :

string fg= "4";
string jn ="22";
// Werte von fg,jn wurden vorher zugewiesen, class "test" deklariert

string name = "Ezt" + fg + jn; // hier würde immer ein neuer Name erzeugt werden

test name = new test (fg,jn);
// hier der Fehler: das funktioniert leider nicht (wäre auch zu schön ;) )

Da ich gerade nichtmal weiß, ob das überhaupt funktioniert wäre ich wirklich froh, wenn mir jemand helfen könnte.

Mfg Maggie

Moderationshinweis von Coffeebean (09.11.2015 - 07:31:54):

Bitte benutze die richtigen Code-Tags [Hinweis] Wie poste ich richtig? Punkt 6

private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7581
Herkunft: Waidring

beantworten | zitieren | melden

Hallo Maggie123,
Zitat
Da ich nicht weiß wieviele es werden, kann ich diese aber nicht genau benennen.
Vermutlich geht es in die Richtung von [FAQ] Variablennamen zur Laufzeit zusammensetzen / Dynamisches Erzeugen von Controls.
Zitat
Während der Laufzeit sollen neue Klassen erstellt werden.
Das geht mittels [Artikel] Reflection und Metaprogrammierung

mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Member

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1551
Herkunft: Düsseldorf

beantworten | zitieren | melden

Wenn Du noch nicht lange mit C# arbeitest, dann suche dir bloß einen anderen Weg aus ;)
Klassen zur Laufzeit erzeugen ist kein kleines Thema und spätestens bei den Methoden brauchst Du detailliertes Wissen, was der Compiler aus C# macht. Am Ende steht da nämlich CIL-Code und viele C#-Features, gibt es auf dieser Ebene nicht mehr und müssen händisch nach gebaut werden.
Du kannst es dir auch etwas einfacher machen und C#-Code generieren und dann kompilieren. Das geht zur Laufzeit, aber auch das wird schnell sehr umfangreich und es ist langsam.


In den meisten Fällen gibt es aber bessere Lösungen.
Wenn es z.B. darum geht, eine unbekannte Anzahl von Eigenschaften einem Objekt zuzuordnen, kannst Du z.B. folgendes machen:

public class MyClass
{
    private readonly IDictionary<string, object> _propertyValues;

    public IEnumerable<string> Properties
    {
        get { return _propertyValues.Keys; }
    }

    public MyClass(string[] propertieNames)
    {
        _propertyValues = propertieNames.ToDictionary(x => x, x => null);
    }

    public bool HasProperty(string propertyName)
    {
        return _propertyValues.ContainsKey(propertyName);
    }
    public object GetValue(string propertyName)
    {
        return _propertyValues[propertyName];
    }
    public void SetValue(string propertyName, object newValue)
    {
        _propertyValues[propertyName] = newValue;
    }
}

Bei der Nutzung, z.B. Darstellung der Daten in einem Fenster, musst Du dann natürlich über die entsprechenden Methoden auf die Werte zugreifen.
Das ist eine gängige Herangehensweise, wenn nicht bekannt ist, wie sich eine Klasse zur Laufzeit zusammen setzen wird.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Palladin007 am .
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

ich denke wie gfoidl, dass [FAQ] Variablennamen zur Laufzeit zusammensetzen / Dynamisches Erzeugen von Controls der Sache am nächsten kommt.

@Palladin007
Bei dynamisch zu erzeugenden Properties funzt das mit dem Dictionary natürlich, aber statt einer GetValue- und SetValue-Methode fände ich hier einen Indexer schöner.
Das Dictionary hat aber allgemien den Nachteil, dass man immer bei GetValue den Rückgabewert nochmal casten muss.

Wenn man bei der Erzeugung schon weiss, wie die Properties heissen sollen (aber nur dann), könnte man ggf. auch mit anonymen Typen arbeiten.

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
Ezio
myCSharp.de - Member

Avatar #avatar-3575.png


Dabei seit:
Beiträge: 196

beantworten | zitieren | melden

Hallo Maggie123.
Zitat
[...]ich arbeite noch nicht lange mit C#[...]
Ich hoffe du nimmst mir meine Gegenfrage nicht übel:
Meinst du wirklich Klassen oder meinst du Instanzen (einer Klasse) bzw. Objekte?

Vielleicht macht es auch Sinn, wenn du dein zugrunde liegendes Problem beschreibst, weshalb du meinst mehrere Klassen zur Laufzeit zu erstellen.
Es könnte auch eine Option sein mit Generics zu arbeiten (openbook: Visual C# Generische Datentypen).

VG Ezio
private Nachricht | Beiträge des Benutzers
Maggie123
myCSharp.de - Member



Dabei seit:
Beiträge: 4

Themenstarter:

beantworten | zitieren | melden

Hallo,

Vielen Dank für die Antworten!

Entschuldigt, da habe ich mich wohl falsch ausgedrückt, ich will neue Instanzen einer Klasse erstellen.

Kurze Beschreibung:

Ich bekomme ein Telegramm, welches aus unterschiedlich vielen Einzeltelegrammen besteht, diese haben wiederum noch mehr Untertelegramme. Ich versuche jetz die Telegramme in Einzeltelegramme aufzuspalten. Ich hab mir davor einen Code gebastelt, aus welchem ich lesen kann, wieviele Einzeltelegramme es gibt, und wie lang diese sind.
Nun war meine Idee, für jedes Einzeltelegramm eine Instanz einer Klasse "Einzeltelegramm" anzulegen. Dort würde ich die verschiedenen Eigenschaften speichern und eventl Methoden zum weiteraufspalten.


Ich habe also schon eine Klasse "Einzeltelegramm" erstellt, habe ihr auch schon Eigenschaften zugewiesen usw.
So... ich will also zur Laufzeit neue Instanzen der Klasse "Einzeltelegramm" erstellen. Aber ich kann diese ja schlecht per Hand benennen.
Ich kann zwar eine String Variable "Name" erstellen, und diese dann so füllen, dass es keine doppelten Namen gibt.
Jedoch funktioniert
einzeltelegram name = new einzeltelegramm (daten);
nicht.

Problem:

Und genau hier liegt mein Problem. Also ich habe alle Daten, die ich für die Klasse brauche, Klasse ist auch schon erstellt, aber ich weiß nicht wie ich hier neue Instanzen erstellen soll, ohne dass ich ihr direkt einen Namen geben kann.


Ich hoffe, ich hab diesmal nicht wieder formulierungsfehler in der Fragestellung.
private Nachricht | Beiträge des Benutzers
inflames2k
myCSharp.de - Experte

Avatar #AARsmmPEUMee0tQa2JoB.png


Dabei seit:
Beiträge: 2361

beantworten | zitieren | melden

Hallo Maggie123,

ich denke du hast hier ein klares Verständnisproblem. In welcher Form erhältst du das Telegram?

Die Zuweisung von Daten über den Konstruktor einer Klasse geht nur dann, wenn es auch einen Konstruktor gibt, der diese Daten entgegen nimmt.

Ansonsten sofern ich dich richtig verstehe:

Telegrammliste erstellen

Für jeden Telegramdatensatz in Ergebnis
      Neues Telegraminstanz erstellen
      Telegraminstanz mit Werten belegen
      Telegraminstanz zu Telegramliste hinzufügen

Weitere Behandlung der Telegramme
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von inflames2k am .
Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager | Spielkartenbibliothek
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

wenn Du die Einzeltelegramme mit einem Namen ansprechen willst, den Du zur Laufzeit zusammensetzt, hilft Dir hier am besten ein Dictionary<string, Einzeltelegramm>.
Da kannst Du dann die einzelnen Instanzen unter ihrem Namen ablegen.

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
witte
myCSharp.de - Member



Dabei seit:
Beiträge: 966

beantworten | zitieren | melden

@Palladin007
Hi,
wieso implementiertst du in deinem Beispiel nicht einfach den Indexer der Klasse?


         public object this[String propertyName]
         {
            get {
                return _propertyValues[propertyName]; 
            }
            set {
                _propertyValues[propertyName] = newValue;
            }
         }

UPPS, hat MarsStein schon angemeckert...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von witte am .
private Nachricht | Beiträge des Benutzers
Taipi88
myCSharp.de - Member

Avatar #avatar-3220.jpg


Dabei seit:
Beiträge: 1044
Herkunft: Mainz

beantworten | zitieren | melden

Hi,

für mich hört sich das klar nach einer Baumstruktur an, in der eine Instanz schlicht weitere Instanzen erzeugt.

public class Telegram
	{
		// übergeordnetes Telegramm (sofern vorhanden)
		public Telegram Parent { get; protected set; }

		// untergeordnete Telegramme - sofern vorhanden
		public List<Telegram> Children { get; set; }

		// Die Eigenschaften des (Einzel)Telegramms
		//...

		public Telegram(string inputToParse, Telegram parent = null)
		{
			Parent = parent;
			Children = new List<Telegram>();
			ParseInput(inputToParse);
		}

		protected virtual void ParseInput(string input)
		{
			// input einlesen - und ggf. weitere Telegramme erstellen
			foreach (string part in input.Split(new char[] {' '})) // nur ein Beispiel
			{
				Telegram child = new Telegram(part, this);
				Children.Add(child);
			}
		}

Edit: Wenn du die dann später in irgend einer Form ausgeben / weiter mit arbeiten möchtest hast die quasi ein Haupttelegramm - und kannst von dort aus schlicht immer tiefer die untergeordneten Telegramme ansprechen.

LG
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Taipi88 am .
private Nachricht | Beiträge des Benutzers
Talon
myCSharp.de - Member



Dabei seit:
Beiträge: 69

beantworten | zitieren | melden

Wie genau willst Du die Einzeltelegramme später weiter verarbeiten? Einfach der Reihe nach oder gezielter Zugriff auf einzelne Telegramme?

Wenn Du die eingehenden Telegramme später nur der Reihe nach abarbeiten willst brauchst Du dir keine Gedanken um Variablennamen zur Laufzeit und ähnliches machen.

Ein kleiner Denkansatz wie Du das z.B. lösen könntest

 List<einzeltelegramm> lstET = new List<einzeltelegramm>();
einzeltelegramm ET = null;

for (int i = 0; i < 1000; i++)
{   //Beispiel 1000 Instanzen
    ET = new einzeltelegramm(daten);
    lstET.Add(ET);
}
private Nachricht | Beiträge des Benutzers
Maggie123
myCSharp.de - Member



Dabei seit:
Beiträge: 4

Themenstarter:

beantworten | zitieren | melden

Super, das geht definitiv in die richtige Richtung

@ inflames2k: Ich hatte die Listen noch nicht im Kopf, aber so ähnlich hatte ich es im Kopf

@Talon: ich will auf die Einzeltelegramme auch noch später zugreifen können, also nicht nur der Reihe nach.

@ Rest:
super, das mit dem Dictionary scheint ziemlich perfekt für dieses Problem zu sein.

Ich habe aber noch eine allgemeine Frage:
Ich müsste meine Instanz der Klasse Einzeltelegramm ja trotzdem benennen. Bspw. "NeuesET". Jetzt die Frage: wäre das OK, für neue Instanzen den selben Namen zu nehmen, wenn ich diese mit!"= new Einzeltelegramm(daten); " erstelle?

Demnach müssten die Werte in der Dictionary immer "NeuesET" heißen, aber mit unterschiedlichen Werten befüllt sein.


Code in der Schleife:

einzeltel NeuesET= new einzeltel(l, fg, id, jn, anzde, daten);

                nameeinzeltelegram.Add((i + 1), NeuesET);
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Maggie123 am .
private Nachricht | Beiträge des Benutzers
inflames2k
myCSharp.de - Experte

Avatar #AARsmmPEUMee0tQa2JoB.png


Dabei seit:
Beiträge: 2361

beantworten | zitieren | melden

Hallo,

der Variablenname ist Schall und Rauch. Nachdem du das Objekt zum Dictionary hinzugefügt hast steht da nicht drin "Objekt NeuesET" sondern "Objekt vom Typ Einzeltelegram".
Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager | Spielkartenbibliothek
private Nachricht | Beiträge des Benutzers
Maggie123
myCSharp.de - Member



Dabei seit:
Beiträge: 4

Themenstarter:

beantworten | zitieren | melden

super, vielen Danke, ihr habt mir echt geholfen!
private Nachricht | Beiträge des Benutzers