Ich möchte sagen:
public void Problem(Guid optional = Guid.Empty)
{
}
Der Compiler beschwert sich jedoch, dass Guid.Empty keine Kompilierungszeitkonstante ist.
Da ich die API nicht ändern möchte, kann ich nicht verwenden:
Nullable<Guid>
c#
c#-4.0
optional-parameters
Ian Ringrose
quelle
quelle
Nullable<Guid> optional = null
(oder knapperGuid? optional = null
) zu wechseln ? Alle Guids, die derzeit an sie übergeben werden, werden gezwungen, ohne dass Codeänderungen erforderlich sind.Antworten:
Lösung
Sie können
new Guid()
stattdessen verwendenSie können auch verwenden
default(Guid)
default(Guid)
wird auch genau so funktionierennew Guid()
.Da Guid ein Werttyp ist, der kein Referenztyp
default(Guid)
ist, entspricht ernull
beispielsweise nicht dem Aufruf des Standardkonstruktors.Was bedeutet, dass dies:
Es ist genau das gleiche wie im Originalbeispiel.
Erläuterung
Warum hat es nicht
Guid.Empty
funktioniert?Der Grund, warum Sie den Fehler erhalten, ist
Empty
folgender:Es ist also eine Variable, keine Konstante (definiert als
static readonly
nicht alsconst
). Der Compiler kann nur vom Compiler bekannte Werte als Standardwerte für Methodenparameter haben (nicht nur zur Laufzeit bekannt).Die Hauptursache ist, dass Sie keine haben
const
könnenstruct
, anders alsenum
zum Beispiel. Wenn Sie es versuchen, wird es nicht kompiliert.Der Grund ist noch einmal, dass
struct
es sich nicht um einen primitiven Typ handelt.Eine Liste aller primitiven Typen in .NET finden Sie unter http://msdn.microsoft.com/en-gb/library/system.typecode.aspx
(beachten Sie, dass
enum
normalerweise geerbt wirdint
, was ein primitiver Typ ist).Ist
new Guid()
aber auch keine Konstante!Ich sage nicht, dass es eine Konstante braucht. Es braucht etwas, das in der Kompilierungszeit entschieden werden kann.
Empty
ist ein Feld, daher ist sein Wert in der Kompilierungszeit nicht bekannt (nur zu Beginn der Laufzeit).Der Standardparameterwert muss zur Kompilierungszeit bekannt sein. Dies kann ein
const
Wert sein oder etwas, das mit einer C # -Funktion definiert wurde, die den Wert zur Kompilierungszeit bekannt macht, wiedefault(Guid)
odernew Guid()
(der zur Kompilierungszeit fürstruct
s festgelegt wird, da Sie denstruct
Konstruktor in nicht ändern können Code).Während Sie bereitstellen können
default
odernew
einfach, können Sie kein a bereitstellenconst
(da es sich nicht um einen primitiven Typ oder einenenum
wie oben erläuterten handelt). Wenn Sie also nicht sagen, dass der optionale Parameter selbst einen konstanten, aber vom Compiler bekannten Wert benötigt.quelle
new Guid()
ist zum Beispiel kein konstanter Ausdruck. Die C # -Spezifikation definiert ganz klar, was erlaubt ist, einschließlich, aber nicht beschränkt auf Konstanten. (Just klar zu sein, ist es effektiv ist eine Kompilierung konstant, nur nicht ein „konstanter Ausdruck“ in C # spec Begriffe).default
heutzutage verwenden :)Guid.Empty
ist äquivalent zunew Guid()
, was äquivalent zu istdefault(Guid)
. So können Sie verwenden:oder
Beachten Sie, dass der
new Foo()
Wert nur gilt, wenn:Foo
ist ein WerttypMit anderen Worten, wenn der Compiler weiß, dass es wirklich nur der Standardwert für den Typ ist :)
(Interessanterweise bin ich zu 99,9% sicher, dass kein benutzerdefinierter
new Foo()
Konstruktor aufgerufen wird, den Sie möglicherweise erstellt haben. Sie können einen solchen Konstruktor nicht in einem Werttyp in C # erstellen, aber Sie können dies in IL tun.)Sie können die
default(Foo)
Option für jeden Typ verwenden.quelle
Nullable<Guid>
.Kannst du nicht benutzen:
default ( Guid )
?quelle
Operator '??' cannot be applied to operands of type 'System.Guid' and 'System.Guid'
Die akzeptierte Antwort funktioniert in ASP.NET MVC nicht und verursacht diesen Laufzeitfehler:
Stattdessen können Sie Folgendes tun:
quelle
Der Compiler ist ganz richtig;
Guid.Empty
ist keine Kompilierungszeitkonstante. Sie können versuchen, eine Methodenüberladung wie folgt durchzuführen:quelle
Guid x = default(Guid)
als Lösung damit einverstanden bin , denken Sie daran, dass das Hinzufügen einer weiteren Funktionsüberladung die API nicht mehr kompliziert als das Hinzufügen eines optionalen Arguments. Das ist es wirklich, was ein optionales Argument sowieso tut.