Übergeben nur eines Typs als Parameter in C #

128

Hypothetisch wäre es für mich praktisch, dies zu tun:

foo.GetColumnValues(dm.mainColumn, int)
foo.GetColumnValues(dm.mainColumn, string)

Dabei ruft die GetColumns-Methode je nach übergebenem Typ eine andere Methode auf.

Ja, ich könnte es als boolesche Flagge oder ähnliches tun. Ich habe mich nur gefragt, ob es einen Weg gibt, dies vielleicht zu bestehen, und dann gefragt:

typeof (arg [1]) oder ähnliches ...

Ich könnte auch die Methode überschreiben, Generika verwenden usw. - Ich weiß, dass es verschiedene Möglichkeiten gibt, dies zu tun. Ich war nur neugierig, ob dies möglich ist.

Mark Mayo
quelle
Mein Gedanke genau, je nachdem was foo eigentlich ist. foo.GetColumnValues<int>(dm.mainColumn)kann der richtige Weg sein.
Wichtiger Productions
1
Wie gesagt, mir ist klar, dass es andere Möglichkeiten gibt, dies zu tun (Boolesches Flag, Generika, Überschreiben der Methode). Ich habe mich nur gefragt, ob dies als Parameter möglich ist.
Mark Mayo
@MarkMayo: Ich verstehe die Frage nicht, wenn Sie "wissen, dass Sie die Methode auch überschreiben, Generika usw. verwenden können und Sie wissen, dass es verschiedene Möglichkeiten gibt, dies zu tun. Sie waren nur neugierig, ob dies möglich ist" . Sie wissen das alles, sind aber neugierig, ob es möglich ist?
Tim Schmelter
@ TimSchmelter - in der von mir beschriebenen Form. dh es als 2. Parameter übergeben. Wie sich herausstellt, hat Reed irgendwie gesagt, wonach ich gesucht habe - wo Sie es verwenden (..., Typ Typ). Das habe ich gesucht.
Mark Mayo
1
Gute Frage, positiv bewertet, ich sehe, dass MS Type als Parameter für integrierte Operatoren in VB.NET verwendet, z. B. Trycast, und habe mir oft gewünscht, dass ich das selbst in C # / VB tun könnte - auf die von Ihnen beschriebene Weise.
Chalky

Antworten:

213

Es gibt zwei gängige Ansätze. Zuerst können Sie bestehenSystem.Type

object GetColumnValue(string columnName, Type type)
{
    // Here, you can check specific types, as needed:

    if (type == typeof(int)) { // ...

Dies würde heißen wie: int val = (int)GetColumnValue(columnName, typeof(int));

Die andere Option wäre die Verwendung von Generika:

T GetColumnValue<T>(string columnName)
{
    // If you need the type, you can use typeof(T)...

Dies hat den Vorteil, dass das Boxen vermieden wird und eine gewisse Typensicherheit geboten wird, und wird wie folgt bezeichnet: int val = GetColumnValue<int>(columnName);

Reed Copsey
quelle
1
Sie können auch eine Erweiterungsmethode ausführen, public static T GetColumnValue <T> (diese Zeichenfolge columnName) {...}, dann können Sie foo.GetColumnValues ​​<string> (dm.mainColumn) sagen
Joshua G
Aber wie definieren Sie eine Methode mit mehreren Argumenten, von denen eines generisch sein sollte? Da das Generikum vor der Methodenargumentliste definiert ist, woher wissen Sie, welches dann ein Generikum sein sollte?
BadmintonCat
5
@ BadmintonCat T Foo<T,U>(string arg1, U arg2)oder ähnliches
Reed Copsey
Gibt es bei Verwendung des ersten Ansatzes eine Möglichkeit, dem Typ einen Standardwert zuzuweisen? (zB so etwas wie object GetColumnValue(string columnName, Type type = object)? Das scheint für mich nicht ganz zu funktionieren, aber es wäre nützlich zu wissen.
Dave Cole
21

foo.GetColumnValues(dm.mainColumn, typeof(string))

Alternativ können Sie eine generische Methode verwenden:

public void GetColumnValues<T>(object mainColumn)
{
    GetColumnValues(mainColumn, typeof(T));
}

und Sie könnten es dann verwenden wie:

foo.GetColumnValues<string>(dm.mainColumn);
Peter Ritchie
quelle
13

Sie können einen Typ als Argument übergeben. Dazu müssen Sie jedoch Folgendes verwenden typeof:

foo.GetColumnValues(dm.mainColumn, typeof(int))

Die Methode müsste einen Parameter mit Typ akzeptieren Type.


Dabei ruft die GetColumns-Methode je nach übergebenem Typ eine andere Methode auf.

Wenn Sie dieses Verhalten wünschen, sollten Sie den Typ nicht als Argument übergeben, sondern stattdessen einen Typparameter verwenden.

foo.GetColumnValues<int>(dm.mainColumn)
Mark Byers
quelle
8
foo.GetColumnValues(dm.mainColumn, typeof(int));
foo.GetColumnValues(dm.mainColumn, typeof(string));

Oder mit Generika:

foo.GetColumnValues<int>(dm.mainColumn);
foo.GetColumnValues<string>(dm.mainColumn);
Danny Varod
quelle
3
Ich habe Sie nicht angesprochen, aber es war wahrscheinlich, weil Sie zeigen, wie es aufgerufen werden würde, und die Funktionsdefinition nicht angegeben haben
JConstantine
3
Ich hasse es, wenn Leute Löffel füttern müssen. Die Antwort + ein wirklich kurzes Lesen von MSDN ist genug. Ich vermute, dass die Abwärtswähler Antwortende sind, die um Repräsentanten konkurrieren - wie kleinlich.
Danny Varod
1

Sie können dies tun, wickeln Sie es einfach ein typeof()

foo.GetColumnValues(typeof(int))

public void GetColumnValues(Type type)
{
    //logic
}
Kevin DiTraglia
quelle
0

Sie können ein Argument vom Typ Type - iow, pass typeof (int) verwenden. Sie können Generika auch für einen (wahrscheinlich effizienteren) Ansatz verwenden.

500 - Interner Serverfehler
quelle
0

Verwenden Sie generische Typen!

  class DataExtraction<T>
{
    DateRangeReport dateRange;
    List<Predicate> predicates;
    List<string> cids;

    public DataExtraction( DateRangeReport dateRange,
                           List<Predicate> predicates,
                           List<string> cids)            

    {
        this.dateRange = dateRange;
        this.predicates = predicates;
        this.cids = cids;
    }
}

Und nenne es so:

  DataExtraction<AdPerformanceRow> extractor = new DataExtraction<AdPerformanceRow>(dates, predicates , cids);
Boris Detry
quelle