Ich erhalte den oben genannten Fehler und kann ihn nicht beheben. Ich habe ein bisschen gegoogelt, kann es aber nicht loswerden.
Szenario:
Ich habe die Klasse BudgetAllocate, deren Eigenschaft das Budget ist, das vom doppelten Typ ist.
In meinem dataAccessLayer
In einer meiner Klassen versuche ich Folgendes:
double.TryParse(objReader[i].ToString(), out bd.Budget);
Welches wirft diesen Fehler:
Eigenschaft oder Indexer dürfen zur Kompilierungszeit nicht als out- oder ref-Parameter übergeben werden.
Ich habe es sogar versucht:
double.TryParse(objReader[i].ToString().Equals(DBNull.Value) ? "" : objReader[i].ToString(), out bd.Budget);
Alles andere funktioniert einwandfrei und Referenzen zwischen den Ebenen sind vorhanden.
c#
.net
error-handling
Pratik
quelle
quelle
DataGrid
, dass sie ausgefüllt werden, um dann nur Autos mit Eigenschaften zu lernen. Durch das Wechseln zu Eigenschaften wurden einige Ref-Parameter beschädigt, die ich für meine Felder verwendet habe. Muss lokale Variablen definieren, mit denen das Parsen durchgeführt werden soll.Antworten:
Sie können nicht verwenden
Ersetzen Sie bd.Budget durch eine Variable.
quelle
Andere haben Ihnen die Lösung gegeben, aber warum dies notwendig ist: Eine Eigenschaft ist nur syntaktischer Zucker für eine Methode .
Wenn Sie beispielsweise eine Eigenschaft deklarieren, die
Name
mit einem Getter und einem Setter aufgerufen wird, generiert der Compiler unter der Haube tatsächlich Methoden mit dem Namenget_Name()
undset_Name(value)
. Wenn Sie dann aus dieser Eigenschaft lesen und in sie schreiben, übersetzt der Compiler diese Operationen in Aufrufe dieser generierten Methoden.Wenn Sie dies berücksichtigen, wird klar, warum Sie eine Eigenschaft nicht als Ausgabeparameter übergeben können - Sie würden tatsächlich einen Verweis auf eine Methode übergeben , anstatt einen Verweis auf
ein Objekt,eine Variable , wie es ein Ausgabeparameter erwartet.Ein ähnlicher Fall besteht für Indexer.
quelle
Dies ist ein Fall einer undichten Abstraktion. Eine Eigenschaft ist eigentlich eine Methode, die get und set Accessoren für einen Indexer get_Index kompilierten get () und set_Index Methoden. Der Compiler leistet hervorragende Arbeit, indem er diese Tatsache verbirgt. Er übersetzt beispielsweise automatisch eine Zuweisung zu einer Eigenschaft in die entsprechende set_Xxx () -Methode.
Dies geht jedoch schief, wenn Sie einen Methodenparameter als Referenz übergeben. Dazu muss der JIT-Compiler einen Zeiger auf den Speicherort des übergebenen Arguments übergeben. Das Problem ist, dass es keine gibt. Um den Wert einer Eigenschaft zuzuweisen, muss die Setter-Methode aufgerufen werden. Die aufgerufene Methode kann den Unterschied zwischen einer übergebenen Variablen und einer übergebenen Eigenschaft nicht erkennen und kann daher nicht wissen, ob ein Methodenaufruf erforderlich ist.
Bemerkenswert ist, dass dies tatsächlich in VB.NET funktioniert. Beispielsweise:
Der VB.NET-Compiler löst dieses Problem, indem er diesen Code für die Run-Methode automatisch generiert, ausgedrückt in C #:
Welches ist die Problemumgehung, die Sie auch verwenden können. Ich bin mir nicht ganz sicher, warum das C # -Team nicht denselben Ansatz gewählt hat. Möglicherweise, weil sie die potenziell teuren Getter- und Setter-Anrufe nicht verbergen wollten. Oder das völlig nicht diagnostizierbare Verhalten, das auftritt, wenn der Setter Nebenwirkungen hat, die den Eigenschaftswert ändern, verschwindet nach der Zuweisung. Klassischer Unterschied zwischen C # und VB.NET, C # ist "keine Überraschungen", VB.NET ist "dafür sorgen, dass es funktioniert, wenn Sie können".
quelle
Platzieren Sie den out-Parameter in einer lokalen Variablen und setzen Sie die Variable dann in
bd.Budget
:Update : Direkt von MSDN:
quelle
Möglicherweise von Interesse - Sie könnten Ihre eigenen schreiben:
quelle
Dies ist ein sehr alter Beitrag, aber ich ändere den akzeptierten, weil es einen noch bequemeren Weg gibt, dies zu tun, den ich nicht kannte.
Es heißt Inline-Deklaration und war möglicherweise immer verfügbar (wie bei der Verwendung von Anweisungen) oder wurde in solchen Fällen mit C # 6.0 oder C # 7.0 hinzugefügt, nicht sicher, funktioniert aber trotzdem wie ein Zauber:
Inetad davon
benutze das:
quelle
Budget ist also eine Eigenschaft, richtig?
Setzen Sie es lieber zuerst auf eine lokale Variable und setzen Sie dann den Eigenschaftswert darauf.
quelle