Was entspricht dem Standardschlüsselwort C # in F #?

79

Ich suche nach dem Äquivalent des defaultSchlüsselworts C # , z.

public T GetNext()
{
    T temp = default(T);
            ...

Vielen Dank

Stringer
quelle

Antworten:

88

Ich fand dies in einem Blog: " Wie sieht dieser C # -Code in F # aus? (Teil eins: Ausdrücke und Anweisungen) "

C # hat einen Operator namens "default", der den Nullinitialisierungswert eines bestimmten Typs zurückgibt:

default(int) 

Es hat einen begrenzten Nutzen; Am häufigsten können Sie Standard (T) in einem Generikum verwenden. F # hat ein ähnliches Konstrukt wie eine Bibliotheksfunktion:

Unchecked.defaultof<int>
blau
quelle
34

Technisch gesehen entspricht die F # -Funktion Unchecked.defaultof<'a>dem defaultOperator in C #. Ich denke jedoch, dass es erwähnenswert ist, dass dies in F # defaultofals unsicher angesehen wird und nur verwendet werden sollte, wenn es wirklich notwendig ist (genau wie die Verwendung null, von der auch in F # abgeraten wird).

In den meisten Situationen können Sie die Notwendigkeit vermeiden, defaultofindem Sie den option<'a>Typ verwenden. Damit können Sie die Tatsache darstellen, dass ein Wert noch nicht verfügbar ist.

Hier ist jedoch ein kurzes Beispiel, um die Idee zu demonstrieren. Der folgende C # -Code:

    T temp = default(T);
    // Code that may call: temp = foo()
    if (temp == default(T)) temp = bar(arg)
    return temp;

Würde wahrscheinlich so in F # geschrieben sein (unter Verwendung zwingender Merkmale):

    let temp = ref None
    // Code that may call: temp := Some(foo())
    match !temp with 
    | None -> bar(arg)
    | Some(temp) -> temp

Dies hängt natürlich von Ihrem spezifischen Szenario ab und ist in einigen Fällen defaultofdas einzige, was Sie tun können. Ich wollte jedoch nur darauf hinweisen, dass dies defaultofin F # weniger häufig verwendet wird.

Tomas Petricek
quelle
1
In Ihrem C # -Beispiel verwenden Sie einen Zuweisungsoperator anstelle eines Gleichheitsoperators in der if-Anweisung. Ist das absichtlich?
Doppelgreener
Ich sollte sagen, dass es bei mir nicht funktioniert. Lassen Sie t = ref Keine t: = Einige (context.Items.FirstOrDefault (fun ii -> ii.Name = i.Name)) stimmen mit | t mit | überein Einige davon -> - sind hier fertig, auch wenn es null ist Keine -> ignorieren
Martin Bodocky
@MartinBodocky Ihr Code wird immer zurückgegeben Some(_). Entweder wird zurückgegeben, Some(value)oder Some(defaultof<>)beide stimmen mit dem Some _Fall in Ihrem Übereinstimmungsausdruck überein. Sie könnten context.Items |> Seq.tryFind(fun II -> ii.Name = i.Name)dann verwenden, der Match-Ausdruck würde wie erwartet funktionieren
Rune FS