myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Grundlagen von C# » Wie kann ich eine Klasse als Methoden-Parameter in Methode übergeben?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Wie kann ich eine Klasse als Methoden-Parameter in Methode übergeben?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
CrocodileDundee
myCSharp.de-Mitglied

Dabei seit: 23.03.2018
Beiträge: 43


CrocodileDundee ist offline

Wie kann ich eine Klasse als Methoden-Parameter in Methode übergeben?

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo zusammen,
ich möchte einer Methode einen Klassennamen als Parameter übergeben.
Also praktisch folgendermaßen:

C#-Code:
public class Auto()
{
     ...
}

public class Person()
{
     ...
}


public class TuWasMitDerKlasse(Klasse)
{
     ...
}

Die Klasse "TuWasMitDerKlasse" bekommt in diesem Fall also entweder "Auto" oder "Person" als Parameter übergeben.

Habs schon versucht mit

C#-Code:
public class TuWasMitDerKlasse(typeof(Klasse))
{
     ...
}

oder mit

C#-Code:
public class TuWasMitDerKlasse(class Klasse)
{
     ...
}

Geht beides nicht. Kann mir jemand vielleicht eine Tipp geben?

Danke und Gruß
Frank
08.10.2019 09:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
BhaaL BhaaL ist männlich
myCSharp.de-Mitglied

Dabei seit: 14.02.2008
Beiträge: 631
Entwicklungsumgebung: VS2017


BhaaL ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Bist du eventuell auf der Suche nach  Generics?

An der Stelle aber der Hinweis: Nur weil du etwas generisch machen kannst, heißt das nicht notwendigerweise, dass du es auch generisch machen solltest. Aber das kannst du nur selbst aufgrund deiner Anforderungen feststellen.
08.10.2019 09:47 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
inflames2k inflames2k ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 2.231
Entwicklungsumgebung: Visual Studio 2010 Express


inflames2k ist online

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Die wichigste Frage ist ja, was du erreichen möchtest. Was soll denn in TuWasMitDerKlasse passieren?
Willst du eine Instanz übergeben oder tatsächlich nur den Typ?

C#-Code:
public class TuWasMitDerKlasse(Klasse)

Das ist im übrigen alles, nur keine gültige Notation zur Definition einer Klasse.

Wie BhaaL gehe ich davon aus, dass du nach Generics suchst. Also etwas in der Richtung:

C#-Code:
public class TuWasMitDerKlasse<TKlasse>
{
     public TuWasMitDerKlasse(TKlasse klasse)
     {
     }
}

Allerdings erschließt sich mir nicht, was Auto und Person gemeinsam haben könnten, dass sie mit einer gemeinsamen Verarbeitungslogik verarbeitet werden könnten.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von inflames2k am 08.10.2019 10:01.

08.10.2019 10:00 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.470
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Generics machen aber nur Sinn, wenn die Klassen über eine gemeinsame Basisklasse (bzw. Interface) verfügen, ansonsten kann innerhalb der generischen Methode nur auf Methoden von Object zugegriffen werden.

Die andere Möglichkeit wäre (du warst schon fast auf dem richtigen Weg):

C#-Code:
public void TuWasMitDerKlasse(Type type)
{
     ...
}

Und dann als Parameter typeof(Auto) übergeben - aber auch hier kannst du dann direkt nur auf Methoden der Klasse Type zugreifen, d.h.  Reflection benutzen.

PS: Als Rückgabewert class bei der Methode zu benutzen, war hoffentlich nur ein Schreibfehler (und kein Verständnisfehler)?!
08.10.2019 12:43 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Coffeebean Coffeebean ist männlich
myCSharp.de-Team

avatar-3295.gif


Dabei seit: 25.08.2011
Beiträge: 2.195
Entwicklungsumgebung: VS 2005-2017, VS Code
Herkunft: Deutschland/Schweiz


Coffeebean ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo CrocodileDundee,

vielleicht verstehe ich die Sache auch falsch, aber wieso kannst du nicht ein Interface nehmen und das als Parameter übergeben?

C#-Code:
public interface IIrgendwas
{
    TuEtwas();
}

public class Auto : IIrgendwas
{
    TuEtwas() { ... }
}

public class Person()
{
   TuEtwas() { ... }
}


public class TuWasMitDerKlasse(IIrgendwas klasseDieInterfaceImplementiert)
{
    klasseDieInterfaceImplementiert.TuEtwas();
}

Reflection würde ich nicht einsetzen, wenn du es nicht musst.

Gruss

Coffeebean
08.10.2019 16:55 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.437
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Im Fall des Interfaces wäre aber das besser

C#-Code:
public void TuWasMitDerKlasse<T>(T klasseDieInterfaceImplementiert) where T: class, IIrgendwas
08.10.2019 17:33 Beiträge des Benutzers | zu Buddylist hinzufügen
panicJonny
myCSharp.de-Mitglied

Dabei seit: 14.11.2011
Beiträge: 61


panicJonny ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Huhu, das ist keine ketzerische Frage sondern ernst gemeint. Warum das als generic übergeben?
09.10.2019 10:52 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.437
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das "besser" war aus dem Auge als Software Architekt.
Gründe zB  Why use constraints

Du kannst eben auf ein Generic Einschränkungen setzen, die eben bei einfacher Parametrisierung nicht möglich sind.
09.10.2019 11:43 Beiträge des Benutzers | zu Buddylist hinzufügen
panicJonny
myCSharp.de-Mitglied

Dabei seit: 14.11.2011
Beiträge: 61


panicJonny ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

hm,

die brauche ich aber auch nicht, wenn ich den Parameter vom Typ IIrgendwas mache.

Welchen Vorteil bekomme ich davon statt

Code:
1:
void foo(IIrgendwas param)

Code:
1:
void foo<T>(T param) where t: class, IIrgendwas

zu machen?

Das ist, für mich gesehen, der gleiche Aufruf nur komplizierter

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von panicJonny am 09.10.2019 12:00.

09.10.2019 11:59 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.437
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von panicJonny:
hm,
die brauche ich aber auch nicht, wenn ich den Parameter vom Typ IIrgendwas mache.

Schau Dir bitte den Link an und wie Generics funktionieren.
Das ist eben auch ein Thema von Software Design.

C#-Code:
    public class A
    {
        public void Test()
        {
            IIrgendwas a = new Etwas();
            Etwas b = new Etwas();

            TuWasMitDerKlasse(a);
            TuWasMitDerKlasse(b);
        }

        public void TuWasMitDerKlasse(IIrgendwas klasseDieInterfaceImplementiert) {}
        public void TuWasMitDerKlasse<T>(T klasseDieInterfaceImplementiert) where T : class, IIrgendwas { }
    }

Die Übergabe mit A ruft die Methode mit Interface als Parameter auf.
Die Übergabe mit B eben die Methode mit Interface über die generische Einschränkung auf.

Fällt Dir was auf? :-)

Zitat:
der gleiche Aufruf nur komplizierter

Das ist eine subjektive Aussage (ähnlich wie mein "Besser" ohne Erklärung ;-)
09.10.2019 12:19 Beiträge des Benutzers | zu Buddylist hinzufügen
panicJonny
myCSharp.de-Mitglied

Dabei seit: 14.11.2011
Beiträge: 61


panicJonny ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Sorry, kantische Lehrmethoden funktionieren bei mir heute nicht.

Was ist der Benefit davon, dass ich den Aufruf über ein Generic mache? Und bitte nicht wieder auf den Artikel mit den contstaints verweisen. Der hat mit meiner Frage irgend wie nichts zu tun.

Grüße
09.10.2019 12:23 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.437
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Naja; nur weil Du jetzt keine Lust einen Artikel zu lesen, der *genau* Deine Frage behandelt oder Dich mit Generics und deren Hintergrund nicht beschäftigen magst, springe ich noch lange nicht - nur weil Du schreist ;-)
Wenn für Dich das mit den Generics keinen Sinn macht: okay, kann ich mit leben.
Nutzbar ist hier beides. Mein Hinweis es auf positive Art zu Nutzen, gerade was die Möglichkeiten und Erweiterbarkeiten betrifft, der bleibt.

Viel Erfolg :-)
09.10.2019 12:34 Beiträge des Benutzers | zu Buddylist hinzufügen
panicJonny
myCSharp.de-Mitglied

Dabei seit: 14.11.2011
Beiträge: 61


panicJonny ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich hab mir aus "Verzweiflung" noch mal deine erste Antwort langsam durchgelesen und bin auf diesen Satz gestoßen.

Zitat von Abt:
Das "besser" war aus dem Auge als Software Architekt.

Du kannst eben auf ein Generic Einschränkungen setzen, die eben bei einfacher Parametrisierung nicht möglich sind.

Dein Aufruf startet quasi mit einer Whitelist und schränkt diese dann nachträglich ein (bildlich gesprochen).

Das Interface als Parameter anzugeben schränkt hingegen gleich maximal ein. Was ja an der Stelle für mich Sinnvoll zu sein scheint.

Das enzige, was mir an der Stelle dazu einfällt ist Erweiterbarkeit, falls ich mal ein weiteres Interface supporten soll. Allerdings soll man ja seine Software auch nicht auf absolut jeden möglichen Fall auslegen (overengineering).

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von panicJonny am 09.10.2019 13:06.

09.10.2019 12:47 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.437
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von panicJonny:
iwarum DU das so vorgeschlagen hast. Warum denkst du, ist es besser ein Generic zu benutzen statt das Interface als Parameter zu nehmen.

Es ist ein grundlegendes Thema:

Zitat von Abt:
Das ist eben auch ein Thema von Software Design.

Zitat von Abt:
Du kannst eben auf ein Generic Einschränkungen setzen, die eben bei einfacher Parametrisierung nicht möglich sind.

Das "Grundproblem", dass die Leute keine Constraints kennen, aber kennen sollten.
Denn viele Dinge lassen sich über constraints viel einfacher lösen - zur Compile Zeit - während man immer wieder über Implementierungen stolpert, die instabil zur Laufzeit geprüft werden.
Prinzip: turning runtime errors into compile time errors.
Zusätzlich natürlich das Cast-Thema, zB. bei Rückgaben des Eingangsparameters bei solchen Methoden.
09.10.2019 12:59 Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.470
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Auch ich sehe hier keinen Vorteil in der generischen Variante. Beides wird vom Compiler zur Compile-Zeit geprüft.
Und auch die Einschränkung "class" ist bei Angabe eines Interfaces überflüssig, denn Interfaces funktionieren generell nur bei Klassen (nicht bei Strukturen).

Und worauf du, @Abt, mit deinem Code-Beispiel hinaus willst, kann ich auch nicht sehen?
09.10.2019 13:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MarsStein MarsStein ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3191.gif


Dabei seit: 27.06.2006
Beiträge: 3.138
Entwicklungsumgebung: VS 2013, MonoDevelop
Herkunft: Trier -> München


MarsStein ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

Zitat von Th69:
Und auch die Einschränkung "class" ist bei Angabe eines Interfaces überflüssig, denn Interfaces funktionieren generell nur bei Klassen (nicht bei Strukturen).

Nur zur Richtigstellung: Das stimmt nicht. Auch Strukturen können Interfaces implementieren, und dann auch in auf diese Interfaces eingeschränkten Generics benutzt werden.

Gruß, MarsStein
09.10.2019 15:29 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.470
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ups, hast recht - habe mich davon verleiten lassen, daß Strukturen keine Basisklassen haben können.
Jedoch gibt es wohl Boxing-Probleme damit:  C#: structs and Interface

Meine Hauptfrage an Abt bleibt aber bestehen.
09.10.2019 16:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.437
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Abt:
Das "Grundproblem", dass die Leute keine Constraints kennen, aber kennen sollten.
Denn viele Dinge lassen sich über constraints viel einfacher lösen - zur Compile Zeit - während man immer wieder über Implementierungen stolpert, die instabil zur Laufzeit geprüft werden.
Prinzip: turning runtime errors into compile time errors.
Zusätzlich natürlich das Cast-Thema, zB. bei Rückgaben des Eingangsparameters bei solchen Methoden.

C#-Code:
Interface Methode(Interface x) {}

vs

C#-Code:
T Methode<T>(T x) where T: Interface {}

Generics sind einfach enorm wichtige Bausteine in der Software Architektur von .NET. Sie bieten eine viel höhere Erweiterbarkeit.
Bei der Generic Variante bekomme ich den konkreten Typ zurück - beim Interface nicht.

Dann noch einfache Fakten, die mit meiner eigentlichen Intension von "Besser" nichts zutun hatten:
- Ich kann Klassen bzw. Erweiterungsmethoden ganz anders und optimaler gestalten
- (Achtung Micro-Optimierung): Der Aufruf des Generic ist i.d.R. schneller als über das Interface. Gibts zig Benchmarks und Artikel zu.
- Thema Boxing bei Value Types
- Der generische Weg gilt seit langem auch in vielen Büchern als "idiomatic"
10.10.2019 18:51 Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.470
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Mir ist klar, daß Generics einen Vorteil bilden können (gerade bei Factory-Methoden, welche einen konkreten Typ zurückgeben), in dem konkreten Fall

C#-Code:
public void TuWasMitDerKlasse(IIrgendwas klasseDieInterfaceImplementiert)

jedoch ist das eine typische Signatur von Dependency Injection Methoden (u.a. auch Konstruktoren) - und daher bin ich irritiert, wenn dies dann immer durch Generics ersetzt werden sollte.

Können wir uns darauf einigen, daß ein Entwickler beide Varianten kennen sollte und je nach Anwendungsfall (also z.B. wenn mehr als eine Constraint-Bedingung vorliegt) dann Generics bevorzugen sollte?
11.10.2019 09:52 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.437
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top



Zitat von Th69:
und daher bin ich irritiert, wenn dies dann immer durch Generics ersetzt werden sollte.

Hat ja auch keiner gesagt.
Die Diskussion hat sich auch von meiner eigentlichen, spezifischen Aussage und dessen Hintergrund total verrannt; in meinen Augen - trotz mehrfacher Hinweise - weil man offenbar die Wirkung von Generics nicht bewusst ist und den Sinn nicht verstanden hat.
Daher bin ich auch raus.
11.10.2019 09:53 Beiträge des Benutzers | zu Buddylist hinzufügen
inflames2k inflames2k ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 2.231
Entwicklungsumgebung: Visual Studio 2010 Express


inflames2k ist online

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo CrocodileDundee,

war denn für dich schon etwas brauchbares dabei? Nur um mal zum Kern des Problems zurück zu kehren.
11.10.2019 10:26 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 4 Monate.
Der letzte Beitrag ist älter als 4 Monate.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 18.02.2020 08:37