2009-08-25 12 views
43

Ich weiß, dass ich nicht eine Methode, wie schreiben:Gibt es eine Möglichkeit, anonyme Methode von Methode zurückzugeben?

public var MyMethod() 
{ 
    return new{ Property1 = "test", Property2="test"}; 
} 

Ich kann es anders:

public object MyMethod() 
{ 
    return new{ Property1 = "test", Property2="test"} 
} 

aber ich will nicht die zweite Option tun, weil, wenn ich so tun Ich werde Reflektion benutzen müssen.


Warum ich das tun wollen:

Heute habe ich meine aspx Seite eine Methode innerhalb haben, die eine Datentabelle als Ergebnis zurückgibt und ich kann es nicht ändern, ich habe versucht, diese Datatable ein konvertieren Anonyme Methode mit den Eigenschaften, mit denen ich arbeiten möchte. Ich wollte nicht nur eine Klasse erstellen, um das zu tun, und da ich dieselbe Abfrage mehr als einmal ausführen muss, dachte ich, eine Methode zu erstellen, die einen anonymen Typ zurückgibt, wäre eine gute Idee.

+0

Für was würden Sie es verwenden? Wie sind Sie zu dem Schluss gekommen, dass Sie so etwas tun möchten? – Guffa

+0

@Guffa, ich habe eine Methode innerhalb meiner Aspx-Seite, die eine Datentabelle als Ergebnis zurückgibt. Ich habe versucht, diese Datentabelle in eine anonyme Methode mit den Eigenschaften zu konvertieren, mit denen ich arbeiten möchte. Ich wollte nicht nur eine Klasse erstellen, um das zu tun, und da ich die gleiche Abfrage mehr als einmal durchführen muss, muss ich eine Methode erstellen, die eine anonyme Methode zurückgibt, wäre eine gute Idee. – Cleiton

+1

@Cleiton - es wird viel weniger Aufwand erforderlich sein, um eine Klasse zu erstellen, die die Daten enthält. Ich bin zu der Erkenntnis gekommen, dass ich nicht einfach Klassen erstellen muss, um diese Typen zu definieren, wenn ich anonyme Typen verwenden muss, um Daten einfach zu manipulieren, wenn ich sie von einem Layer zum anderen weitergeben muss. – Jagd

Antwort

57

Rückgabe als System.Object ist die nur Möglichkeit, einen anonymen Typ von einer Methode zurückzugeben. Leider gibt es keine andere Möglichkeit, dies zu tun, da anonyme Typen speziell dafür entwickelt wurden, ihre Verwendung auf diese Weise zu verhindern.

Es gibt einige Tricks, die Sie in Verbindung tun können, ein Object mit der Rückkehr, die Sie erlaubt zu nahe zu kommen. Wenn Sie an dieser Problemumgehung interessiert sind, lesen Sie bitte Can't return anonymous type from method? Really?.

Haftungsausschluss: Obwohl der Artikel, den ich verlinkte, eine Problemumgehung zeigt, bedeutet das nicht, dass es eine gute Idee ist, es zu tun. Ich würde Sie davon abraten, diesen Ansatz zu verwenden, wenn Sie einen regulären Typ erstellen würden, der sicherer und verständlicher wäre.

+10

Es sollte angemerkt werden, dass dies keine empfohlene Idee ist . Intellisense erkennt die stark typisierten Eigenschaften des anonymen Typs (Property1 und Property2 aus Ihrem Beispiel) nicht mehr. Eigentlich können Sie Reflektion verwenden, um an die Eigenschaften zu kommen, aber Sie können auch Ihren Daumen mit Hammer für die ganze Arbeit schlagen, die Sie hineinlegen, und nicht zu erwähnen, dass Sie einfach etwas genommen haben, das Ihr Leben leichter machen sollte , machte es aber tatsächlich schwerer. – Jagd

+0

+1 hätte ich selbst nicht besser sagen können. Ja, es kann gemacht werden, aber das bedeutet nicht, dass es eine gute Idee ist. –

+0

Es kann getan werden! Es ist nur ein p.i.t.a._ –

1

Nein, anonyme Typen nicht außerhalb des Kontextes existieren in dem sie entstehen, und als Ergebnis kann nicht als eine Methode Rückgabetyp verwendet werden. Sie können die Instanz als object zurückgeben, aber es ist eine viel bessere Idee, für diesen Zweck explizit einen eigenen Containertyp zu erstellen.

0

Sorry, Sie sollen wirklich nicht, das zu tun. Sie können es mit Reflektion hacken oder indem Sie eine generische Hilfsmethode verwenden, um den Typ für Sie zurückzugeben, aber dies funktioniert wirklich gegen die Sprache. Erklären Sie einfach den Typ, damit klar ist, was vor sich geht.

2

denke ich, Andrew Hare richtig ist, würden Sie müssen nur zurückkehren „Objekt“. Für einen redaktionellen Kommentar, ich fühle mich wie Umgang mit rohen Objekten in OO-Code kann ein "Code-Geruch." Es gibt Fälle, in denen das Richtige zu tun ist, aber meistens ist es besser, eine Schnittstelle zu definieren, die zurückgegeben werden soll, oder eine Art Basisklasse zu verwenden, wenn Sie verwandte Typen zurückgeben.

1

Nein, es gibt keine Unterstützung für den Umfang der anonymen Klasse außerhalb der Methode zu erweitern. Außerhalb der Methode ist die Klasse wirklich anonym, und Reflektion ist die einzige Möglichkeit, auf ihre Mitglieder zuzugreifen.

13

Die einfachste Lösung ist es, eine Klasse zu erstellen, die Werte in das Eigentum schieben und sie dann zurück. Wenn anonyme Typen dein Leben härter machen, dann verwendest du sie nicht richtig.

13
public object MyMethod() 
{ 
    return new 
    { 
     Property1 = "test", 
     Property2 = "test" 
    }; 
} 

static void Main(..) 
{ 
    dynamic o = MyMethod(); 
    var p1 = o.Property1; 
    var p2 = o.Property2; 
} 
21

Alternativ können Sie die Tuple-Klasse in .NET 4 verwenden.0 und höher:

http://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx

Tuple<string, string> Create() 
{ 
return Tuple.Create("test1", "test2"); 
} 

dann können Sie die Eigenschaften wie folgt zugreifen:

var result = Create(); 
result.Item1; 
result.Item2; 
+8

Lustig. Ich suchte hier nach einer Alternative zur Verwendung von Tupeln als Rückgabetypen. – SixOThree

6

Ungeachtet der Warnungen darüber, ob dies eine gute Idee ist oder nicht ... Ein dynamic scheint gut für eine private Methode zu arbeiten.

private dynamic MyMethod() 
{ 
    return new { Property1 = "test", Property2 = "test" } 
} 
+0

Ich denke, es ist nicht das beste, da dynamische in jeden Datentyp, einschließlich Objekt, eingebaut wird, so dass Sie besser mit Objekt, mit weniger Overhead sein würden. – MrKekson

Verwandte Themen