Warum hat C# nicht lassen Sie mich rufen Sie eine void-Methode, die als Teil der return-Anweisung?
Ich bin neugierig, ob es eine legitime Grund, warum C# keine Unterstützung für den Aufruf einer void-Methode als Teil der return-Anweisung, wenn die aufrufende Methode zurück geben ist ebenfalls ungültig.
public void MethodA()
{
return;
}
public void MethodB()
{
return MethodA();
}
So würden wir normalerweise sehen:
public void MethodMeh()
{
if (expression)
{
MethodA();
return;
}
//Do more stuff
}
... wenn wir könnten mit diesem statt:
public void MethodAwesome()
{
if (expression)
return MethodA();
//Do more stuff
}
Ist dies eine Sprache, die Beschränkung durch wie C# Griffe leere?
- Ich bin sicher, es ist in der Sprache spec. Es wäre sehr irreführend, lassen Sie den return-Schlüsselwort in einem Kontext, in dem kein Wert zurückgegeben wird.
- es ist wie zu sagen - "in dieser Methode, die keinen Wert zurückgibt,können wieder in dieser Methode(die auch nicht zurück)...und so weiter,und..."
- Keines der oben genannten Beispiele gibt eine Methode!
- möglicherweise compiler sucht immer ein ";", gefolgt von
return
keyword beivoid
zurück geben, sonst nichts !!! (Eine Vermutung. Ich bin ein java-dev) - Es gibt nichts, inhärente würde, dass diese unmöglich. Zum Beispiel F# hat die
Unit
geben. Die CLR hat diese ganz spezielle void construct (geerbt von C). Mir scheint es das C-Sprachen sind die ungeraden hier. - Warum würden Sie wollen, zu tun MethodAwesome? Kürzerer code ist nicht besser, code, übersichtlicher code ist besser code. Es sieht aus wie es gibt eine Methode, wenn es nicht sein würde, ist unnessarily verwirrend.
- +1. Tatsächlich, diese Frage könnte erweitert werden zu "warum ist es nicht legal schreiben
return void;
in einer Methode, die Rückgabe eine leere?". Und dann, durch Erweiterung,return f()
wennf
's return-typevoid
. Das problem sehe ich - das kann wirklich bedeuten, die Antwort auf die Frage - ist, dass es kann dazu führen, auf die Frage "warum ist es nicht legal zum schreiben einer Variablen-Deklaration, wievoid x = f()
?". - Es gibt ein weiteres Manko mit einer Umsetzung der vorgeschlagenen syntax. Sie sind mit
return
mit einer Methode, die zurückgibtvoid
, in einem Kontext, der einen Wert erwartet. Also es wäre nur anwendbar, in der Umstand, wo man in einervoid
Methode und aufrufen von anderenvoid
Methode. Andernfalls würde es zu einem compiler-Fehler. Später dann, wenn man entweder wurde verändert, um nichtvoid
syntax brechen würde - während der üblichen syntax wäre weiter gut arbeiten. - Ich glaube ich habe die einzige Antwort, die tatsächlich zeigt, dass der Titel fragt.
- Recht. Wenn Sie einen Vorschlag für einen besseren Titel, Bearbeiten entfernt. "Warum C# keine Unterstützung für die Rückgabe der nicht vorhandene Ergebnis einer Methode, die eine void-Rückgabe-Typ"?
- Ich denke, das wäre ein besserer Titel.
- Lemme wissen, ob, die Frage ist besser; ich versuchte, nicht in die details der 'leere Raum ist nicht ein echter Typ", denn das ist im wesentlichen die Beantwortung Ihrer eigenen Frage 🙂
- wie ist das anders aus, eine Methode, die zurückgibt, ein echter Typ ruft eine andere Methode gibt, die den gleichen Typ?
- Denn es wäre verwirrend, wenn jemand Lesen Sie den code, und es würde sparen Sie nur ein paar Tastenanschläge sowieso. Kürzer ist nicht immer besser.
- Implizite casts. Wenn ich eine Methode, die zurückgibt
IEnumerable<T>
, die nennt man die zurückIEnumerable<T>
, und ich später ändern, das innere zuList<T>
, ich brauche nicht, etwas zu tun. Wenn ich es ändern zuDictionary<T, V>
würde, dann würde ich es ändern müssen, aber das wäre zu erwarten, weil alles, was war, ruft diese Methode auf, um eineIEnumerable<T>
jetzt bekommt neue Daten. Aber die Veränderung vonvoid
zu anderen return-Typ sollte nicht brechen nichts, weil es nichts nutzt einevoid
. - C# erlaubt mir, mich zu nennen, die einen Wert zurückgibt-Methode und ignorieren die Rückkehr geben; wenn diese dumme "void " zurückgeben" syntax legal waren, wäre es leicht genug, um einfach zu verwerfen, die neu-gültig Rückgabetyp der inneren Methode, wenn die äußere Methode war nichtig.
- Es ist wahr, aber dann verlieren Sie die compiler-Fehlermeldung, wenn Sie
return true;
am Ende Ihrervoid
Methode. Aufrufen einer Methode und ignoriert die Rückkehr ist einfach eine Nachricht, nicht einmal eine Warnung, wenn ich mich Recht erinnere. - Weil in
C#
return void;
ist auch ungültig.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Weil es einfach die Art und Weise die Sprache definiert ist.
Es ist eine willkürliche Entscheidung (vermutlich gemacht, um die Kompatibilität mit ANSI-C und dessen andere Nachkommen), und in anderen Sprachen die Dinge anders.
Beispielsweise in Python, werden alle Funktionen geben einen Wert zurück. Wenn Sie führen Sie eine
return
- Anweisung ohne Wert, oder lassen Sie die Kontrolle bis zum Ende der Funktion, dann ist es genau so wie Sie geschrieben hattereturn None
.Im Gegensatz, Pascal Grenzen der Terminologie der
function
an Unterprogramme, die einen Wert zurückgeben, wenn Sie nicht wollen, etwas zurückzugeben, verwenden Sie eineprocedure
statt.void
ist das fehlen von Informationen; es macht keinen Sinn, es zurückzugeben. Es ist nicht eine Art*, und es ist nicht ein Wert, anders als in einigen anderen Sprachen. Nein, das ist nicht wirklich eine Einschränkung.* Na ja, irgendwie schon, da @Lucas Punkte aus. Es ist eine informative Art; es hat nicht wirklich darstellen, ein Typ im üblichen Sinne. Man kann das eine nicht.
System.Void
. Aber es ist eine sehr spezielle Art, in der Tat...void
wenn wirreturn;
innerhalb einer Methode, die einevoid
zurück geben?return
ohne Ausdruck danach ist nicht gültig für eine Methode mit einem Rückgabetyp. Klar, es gibt nichts zurück.null
, und Sie einfach nur return (oder exit) aus void-Funktionen.unit
Typ mit nur einem einzigen Wert stattvoid
gewesen wäre, eine bessere Lösung, natürlich—der resultierende code wäre schon komplett das gleiche.typeof(System.Void)
(Sie haben zu schreibentypeof(void)
statt). Sie können nichtActivator.CreateInstance
zu instanziieren. Sie können nichtExpression.New
zu instanziieren, es entweder. Ich habe nicht versucht, mit IL emittieren. Aber Sie kann verwendenFormatterServices.GetUninitializedObject
um eine Instanz davon. 🙂()
, ist als Wert und Typ an und für sich (obwohl es wird in der Regel erstellt, umvoid
), und Sie können Ereignis binden Variablen. Es sind auch nicht die Funktionen/Methoden, die keine Argumente; stattdessen, nehmen Sieunit
.Void
in Java, die besonderen Regeln in C++ mit templates,..()
ist schön, sicher, aber ich glaube nicht, dass es eine Einschränkung von C# unabhängig, vor allem, da Sie nicht haben, um passieren zu können, eine leere rund zu machen, für sauberen code.void
wie in Java, C++ oder C# ist, dass Sie Beschränkungen so bald wie Generika ins Spiel kommen. Das ist, warum C# muss sowohlAction
undFunction
Delegierten, warum C++ braucht Besondere Regeln für die wenn es ist in Ordnung zureturn void
(implizit) in den templates, und warum JavaVoid
(das ist im Grunde nurunit
).void
. (Es ist, was ich spreche, als auch, wenn Sie sagen, es ist kein Typ.) Der Unterschied zwischenAction
undFunc
ist ein guter Punkt.typeof(System.Void)
sollte machen genauso viel Sinn wietypeof(void)
. Schließlichtypeof(void).FullName == "System.Void"
. Ich seheSystem.Void
wie die null-Objekt für Reflexion Zwecke.typeof(void)
bekommt man den Typ void; Sie können nicht die Art von Typ.System.Type
😉Deine Frage ist ziemlich viel über den Unterschied zwischen die
void
- Typ und dieunit
- Typ (am häufigsten in funktionalen Sprachen wie F#).Grundsätzlich
void
ist nicht ein echter Typ. Zwar gibt esSystem.Void
für Reflexion Zwecke, Sie können nichtvoid
in den meisten Orten, wo Sie verwenden können, ein echter Typ: man kann nicht eine variable vom Typvoid
und Sie können es nicht verwenden, im Bereich der Generika (obwohl schreiben zu könnenFunc<void>
wäre manchmal sehr nützlich).Auf der anderen Seite
unit
in F# ist ein echter Typ: er hat einen (einzigen) Wert (genannt()
), können Sie den Gegenwert vonFunc<void>
(geschriebenunit -> unit
, wo die ersteunit
bedeutet "keine Parameter", ähnlich wie beim schreibenvoid
in der Liste der parameter in C) und man kann Variablen vom Typunit
. Zum Beispiel:Die Letzte Zeile zeigt eigentlich, dass in F# Sie manchmal müssen ausdrücklich zurück
unit
.Func<void>
ist auch alsAction
🙂Task.Factory.StartNew()
nicht über separate überladungen fürFunc<T>
und fürAction
.Task<unit>
etc. Es zeigt eindrucksvoll, dass C# nicht viel von einer funktionalen Sprache in der Anfang. Jetzt hat es zu halten Abwärtskompatibilität, während die Einführung viele funktionale-Paradigmen 🙂Dies ist nicht erlaubt, gemäß der Sprachspezifikation. Von 15.9.4 der ECMA-334 (Hervorhebung von mir):
Kommt es zu Entscheidungen, durch die die Sprache der designer.
Aus einer Perspektive, void hat keine zählbare Werte, so dass es nicht sinnvoll ist, um einen Wert zurückzugeben, der "void" - Typ? leere ist die Abwesenheit von Typ-oder evaluation-context.
Sie können nicht instanziieren oder Rückgabe "void" in C# oder Java.
Wenn Sie so tun könnte, dann sollten Sie auch in der Lage sein zu sagen:
Oben macht keinen Sinn, aber ist äquivalent zu dem, was Sie vorschlagen.
Am Ende, schlägt vor, wir könnten propagieren void-Rückgabe Zusammenhang mit der return-Anweisung ist einfach eine Frage der syntaktischen Zucker, der kommt auf die Optionen, die die Sprache der designer.
Die Sprache C# spec http://msdn.microsoft.com/en-us/library/aa691305(v=vs. 71).aspx
(Abschnitt 7.1) sagt
Auf der anderen verfügen, der C++ - designer tatsächlich ausgewählt haben, dass nur das Konstrukt, das Sie vorschlagen, aber es wurde speziell für die syntaktische Einheitlichkeit in Vorlagen. In C++ die Rückgabe-Typ einer template-Funktion kann ein template-parameter. (Stroustrop C++ Programming Language, S. 148) Ohne es, würde es in häufigen Fällen, die zusammenstellen würde für alle Arten, aber nicht für nichtig, wie verschachtelte Funktionsaufrufe vom Typ T. daher gilt C++:
So die Aussage Ausdruck "return B();" B ist eine void-Funktion ist nur eine Abkürzung für "B(); return;" und nicht wirklich Ertrag einen Wert, denn es gibt keine solche Sache wie ein void-Wert.
void
natürlich. Wie ein Aufruf zu einemvoid
Funktion. Nun, ich kann nicht sehen, warum die Zuweisung einervoid
eine variable jemals nützlich, aber der Sinn der OP ' s Frage ist, dass es könnte wurden implementiert.void
überhaupt. Es ist einfach ein syntaktisches Konstrukt angeben zu können Prozeduren (kein Rückgabewert) sowie Funktionen (einen einzelnen Wert zurückgeben). Natürlich könnten Sie eine Funktion, die immer wiedernull
einigeunit
geben. Aber was wäre der Punkt? Es ist nichtnull
, es ist "nichts". Was wäre der Punkt, der mit Sprache-Funktionen, die die Komplexität erhöhen für jeder noch bieten keine Funktionalität überhaupt?return MethodA();
ist gültiges C++.Ich habe eine Vermutung darüber, einen berechtigten Grund für diese.
Wenn der compiler auf einen Ausdruck, es versucht, ihn auf etwas, das aus einer Liste von bekannten Ausdrücken. Man könnte sagen, dass es zwei Arten von Aussagen, die beginnen mit
return
:return expr
woexpr
ist ein Ausdruck zuordenbar deklarierten Rückgabetyp der Methode mitreturn
ohne wasSind dies völlig unterschiedliche Aussagen, auch wenn Sie ähnlich Aussehen. Aber man kann kompilieren zu den anderen, in bestimmten Fällen (wie
foreach
kompiliert, um einewhile
plus Zeug). So fügen Sie eine Regel, die sagt, dassreturn expr
kompiliert, wasexpr; return;
kompiliert, wennexpr
festgestellt werden, dass es kein zurück mehr geben (das istvoid
).Aber dann die Entwickler von C# - Compiler wäre damit für alle Ausdrücke zu haben, die keine Rückkehr geben, wenn normalerweise nur Aussagen darf es kein zurück geben. Wenn Sie dies getan haben, dann würden Sie haben, um manuell zu verbieten Ausdrücke der kein Typ ist, wo ein tatsächlicher Art erforderlich ist. Zum Beispiel, in der Ausdrücke, die als Argumente an eine Funktion aufrufen
MyMethod(1, 2, SomethingVoid())
, würde der compiler zusätzlich zu prüfen haben, ob diese Ausdrücke nicht wieder eine geben. Und für jede neue Art von Ausdruck Hinzugefügt, um C# in die Zukunft, die gleiche Prüfung haben würden, Hinzugefügt werden.Oben ist möglich, aber es würde passieren, aus keinem anderen Grund als zu erlauben, nicht-Anweisung Ausdrücke in den abstrakten syntax-Baum (das ist erzeugt während der Kompilierung) keine Rückkehr geben, und das wäre der Fall nur zu erlauben, für eine geringfügige syntaktische Struktur - und hat eine alternative, die nicht mehr (bei Tastatureingaben) zu geben und eventuell klarer zu Lesen.
In der end, es klingt nicht, es lohnt sich.
unit
wie ein normaler Typ, der ein singleton. FürMyMethod(1, 2, SomethingVoid())
der compiler bereits prüfen, ob1
(int) ist ein Gültiger Typ für den ersten parameter, etc. Als eine Angelegenheit von der Tat, könnte es einfacher sein, die andere Weise herum, denn gerade jetzt werden Sie wahrscheinlich wirklich noch eine zusätzliche code-Pfad fürvoid
oder benötigen eine komplizierte Allgemeinen Algorithmus zu handhaben ist es auch.Du bist der eigentlichen Frage Titel erscheint nicht abgedeckt werden durch die Antworten, obwohl Sie immer an der richtigen Sache. Du bist der Frage-Titel
Eigentlich in C# wird erlaubt, nur nicht in dem format, das Sie versuchen. Mit der
void
Schlüsselwort als andere beantwortet haben, bedeutet, dass die Methode nichts zurückgibt. Wenn Sie zurückkehren möchten, eine Methode, die nichts zurückgibt, dann willst du etwas wie das hier tun:Dann ein einfacher Aufruf wird Ihnen diese Aktion:
siehe diese Erklärung
Mich korrigieren, wenn ich falsch bin, aber ich denke, dass seine weil:
wäre das gleiche wie(die legal sind):
Und auch:
return VoidMethod();
Stoppt die Ausführung beim Austausch mit einem einfachen Methodenaufruf nicht.