Hoe kan ik een parameter standaard instellen op Guid.Empty in C#?

Hoe kan ik een parameter standaard instellen op Guid.Empty in C#?

Oplossing

U kunt new Guid() . gebruiken in plaats daarvan

public void Problem(Guid optional = new Guid())
{
  // when called without parameters this will be true
  var guidIsEmpty = optional == Guid.Empty;
}

Je kunt ook default(Guid) . gebruiken

default(Guid) werkt ook precies zoals new Guid() .

Omdat Guid een waardetype is en geen referentietype, dus default(Guid) is niet gelijk aan null in plaats daarvan is het bijvoorbeeld gelijk aan het aanroepen van de standaardconstructor.

Wat betekent dat dit:

public void Problem(Guid optional = default(Guid))
{
  // when called without parameters this will be true
  var guidIsEmpty = optional == Guid.Empty;
}

Het is precies hetzelfde als het originele voorbeeld.

Uitleg

Waarom niet Guid.Empty werk?

De reden dat u de foutmelding krijgt, is omdat Empty is gedefinieerd als:

public static readonly Guid Empty;

Het is dus een variabele, geen constante (gedefinieerd als static readonly niet als const ). Compiler kan alleen door de compiler bekende waarden hebben als standaardwaarden voor methodeparameters (niet alleen-runtime-bekend).

De hoofdoorzaak is dat je geen const . kunt hebben van elke struct , in tegenstelling tot enum bijvoorbeeld. Als je het probeert, zal het niet compileren.

De reden is nogmaals dat struct is geen primitief type.
Voor een lijst van alle primitieve typen in .NET zie http://msdn.microsoft.com/en-gb/library/system.typecode.aspx
(merk op dat enum erft meestal int , wat een primitief is)

Maar new Guid() is ook geen constante!

Ik zeg niet dat het een constante nodig heeft. Het heeft iets nodig dat tijdens het compileren kan worden besloten. Empty is een veld, dus de waarde ervan is niet bekend tijdens het compileren (alleen aan het begin van de runtime).

De standaard parameterwaarde moet bekend zijn tijdens het compileren, dit kan een const . zijn waarde, of iets dat is gedefinieerd met behulp van een C#-functie die de waarde bekend maakt tijdens het compileren, zoals default(Guid) of new Guid() (wat tijdens het compileren wordt beslist voor struct s aangezien u de struct . niet kunt wijzigen constructor in code).

Terwijl u default . kunt verstrekken of new gemakkelijk, u kunt geen const . opgeven (omdat het geen primitief type is of een enum zoals hierboven uitgelegd). Dus nogmaals, ik zeg niet dat de optionele parameter zelf een constante nodig heeft, maar de compiler bekende waarde.


Guid.Empty is gelijk aan new Guid() , wat gelijk is aan default(Guid) . U kunt dus het volgende gebruiken:

public void Problem(Guid optional = default(Guid))

of

public void Problem(Guid optional = new Guid())

Merk op dat de new Foo() waarde is alleen van toepassing wanneer:

  • Je noemt echt de parameterloze constructeur
  • Foo is een waardetype

Met andere woorden, als de compiler weet dat het eigenlijk gewoon de standaardwaarde is voor het type :)

(Interessant genoeg weet ik 99,9% zeker dat het niet zal zijn bel een aangepaste new Foo() constructor die u mogelijk hebt gemaakt. Je kunt zo'n constructor niet maken in een waardetype in C#, maar je kunt wel doe dit in IL.)

U kunt de default(Foo) . gebruiken optie voor elke typ.


Kun je niet gebruiken:

default ( Guid ) ?