GenerikaGenerics

F#-Funktionswerte, -Methoden, -Eigenschaften und -Aggregattypen, wie z.B. Klassen und Unterscheidungs-Unions können generisch sein.F# function values, methods, properties, and aggregate types such as classes, records, and discriminated unions can be generic. Generische Konstrukte enthalten mindestens einen Typparameter, die in der Regel vom Benutzer des generischen Konstrukts angegeben wird.Generic constructs contain at least one type parameter, which is usually supplied by the user of the generic construct. Mit generischen Funktionen und Typen können Sie Code schreiben, der mit einer Vielzahl von Typen funktioniert, ohne den Code für jeden Typ zu wiederholen.Generic functions and types enable you to write code that works with a variety of types without repeating the code for each type. Ihren Code generisch zu erstellen kann einfach sein, da Ihr Code häufig implizit abgeleitet wird, um durch den Typrückschluss des Compilers und durch automatische Verallgemeinerungsmechanismen generisch zu sein.Making your code generic can be simple in F#, because often your code is implicitly inferred to be generic by the compiler's type inference and automatic generalization mechanisms.

SyntaxSyntax

// Explicitly generic function.
let function-name<type-parameters> parameter-list =
function-body

// Explicitly generic method.
[ static ] member object-identifer.method-name<type-parameters> parameter-list [ return-type ] =
method-body

// Explicitly generic class, record, interface, structure,
// or discriminated union.
type type-name<type-parameters> type-definition

HinweiseRemarks

Die Deklaration einer explizit generischen Funktion oder eines Typs entspricht weitgehend einer nicht generischen Funktion oder des Typs, mit Ausnahme der Spezifikation (und Verwendung) der Typparameter in spitzen Klammern nach dem Namen der Funktion oder des Typs.The declaration of an explicitly generic function or type is much like that of a non-generic function or type, except for the specification (and use) of the type parameters, in angle brackets after the function or type name.

Deklarationen sind oft implizit generisch.Declarations are often implicitly generic. Wenn Sie den Typ jedes Parameters nicht vollständig angeben, der zum Erstellen einer Funktion oder eines Typs verwendet wird, versucht der Compiler den Typ jedes einzelnen Parameters, Werts und jeder Variablen aus dem Code, den Sie schreiben, abzuleiten.If you do not fully specify the type of every parameter that is used to compose a function or type, the compiler attempts to infer the type of each parameter, value, and variable from the code you write. Weitere Informationen finden Sie unter Type Inference (F#).For more information, see Type Inference. Wenn der Code für Ihren Typ oder die Funktion die Typen der Parameter nicht anderweitig einschränkt, ist die Funktion oder der Typ implizit generisch.If the code for your type or function does not otherwise constrain the types of parameters, the function or type is implicitly generic. Dieser Prozess heißt automatische Verallgemeinerung.This process is named automatic generalization. Es gibt einige Einschränkungen für die automatische Verallgemeinerung.There are some limits on automatic generalization. Wenn beispielsweise der F#-Compiler die Typen für ein generisches Konstrukt nicht ableiten kann, meldet der Compiler einen Fehler, der sich auf eine Einschränkung namens Wertebeschränkung bezieht.For example, if the F# compiler is unable to infer the types for a generic construct, the compiler reports an error that refers to a restriction called the value restriction. In diesem Fall müssen Sie möglicherweise einige Typanmerkungen hinzufügen.In that case, you may have to add some type annotations. Weitere Informationen über die automatische Verallgemeinerung und die Wertebeschränkung, und wie Sie den Code ändern, um das Problem zu lösen, finden Sie unter Automatische Verallgemeinerung.For more information about automatic generalization and the value restriction, and how to change your code to address the problem, see Automatic Generalization.

In der vorherigen Syntax ist type-parameters eine durch Trennzeichen getrennte Liste von Parametern, die unbekannte Typen darstellen, jeweils beginnend mit einem einfachen Anführungszeichen und optional mit einer Einschränkungsklausel, die weiter begrenzt, welche Typen für den Typparameter verwendet werden können.In the previous syntax, type-parameters is a comma-separated list of parameters that represent unknown types, each of which starts with a single quotation mark, optionally with a constraint clause that further limits what types may be used for that type parameter. Die Syntax für Einschränkungsklauseln verschiedener Arten und andere Informationen zu Einschränkungen finden Sie unter Einschränkungen.For the syntax for constraint clauses of various kinds and other information about constraints, see Constraints.

Die type-definition in der Syntax entspricht der Typdefinition für einen nicht generischen Typ.The type-definition in the syntax is the same as the type definition for a non-generic type. Sie enthält die Konstruktorparameter für einen Klassentyp, eine optionale as-Klausel, das gleiche Symbol, die Datensatzfelder, die inherit-Klausel, die Optionen für eine Unterscheidungs-Union, let- und do-Bindungen, die Memberdefinitionen und alles andere, was in einer nicht generischen Typdefinition zulässig ist.It includes the constructor parameters for a class type, an optional as clause, the equal symbol, the record fields, the inherit clause, the choices for a discriminated union, let and do bindings, member definitions, and anything else permitted in a non-generic type definition.

Die anderen Syntaxelemente sind identisch mit denen für nicht generische Funktionen und Typen.The other syntax elements are the same as those for non-generic functions and types. Beispielsweise ist object-identifier ein Bezeichner, der das enthaltende Objekt selbst darstellt.For example, object-identifier is an identifier that represents the containing object itself.

Eigenschaften, Felder und Konstruktoren können nicht generischer als der einschließende Typ sein.Properties, fields, and constructors cannot be more generic than the enclosing type. Außerdem können Werte in einem Modul nicht generisch sein.Also, values in a module cannot be generic.

Implizit generische KonstrukteImplicitly Generic Constructs

Wenn der F#-Compiler die Typen im Code ableitet, behandelt es automatisch alle Funktionen, die als Generische generisch sein können.When the F# compiler infers the types in your code, it automatically treats any function that can be generic as generic. Wenn Sie einen Typ explizit angeben, wie z.B. einen Parametertyp, verhindern Sie die automatische Verallgemeinerung.If you specify a type explicitly, such as a parameter type, you prevent automatic generalization.

Im folgenden Codebeispiel ist makeList generisch, obwohl weder es noch seine Parameter explizit als generisch deklariert werden.In the following code example, makeList is generic, even though neither it nor its parameters are explicitly declared as generic.

let makeList a b =
    [a; b]

Die Signatur der Funktion wird als 'a -> 'a -> 'a list abgeleitet.The signature of the function is inferred to be 'a -> 'a -> 'a list. Beachten Sie, dass a und b in diesem Beispiel abgeleitet werden, um über den gleichen Typ zu verfügen.Note that a and b in this example are inferred to have the same type. Dies ist, da sie zusammen in einer Liste enthalten sind, und alle Elemente einer Liste müssen vom gleichen Typ sein.This is because they are included in a list together, and all elements of a list must be of the same type.

Sie können auch eine Funktion generisch erstellen, indem Sie die Syntax für einfache Anführungszeichen in einer Typanmerkung verwenden, um anzugeben, dass ein Parametertyp ein generischer Typparameter ist.You can also make a function generic by using the single quotation mark syntax in a type annotation to indicate that a parameter type is a generic type parameter. Im folgenden Code ist function1 generisch, da seine Parameter auf diese Weise als Typparameter deklariert werden.In the following code, function1 is generic because its parameters are declared in this manner, as type parameters.

let function1 (x: 'a) (y: 'a) =
    printfn "%A %A" x y

Explizit generische KonstrukteExplicitly Generic Constructs

Sie können eine Funktion auch generisch erstellen, indem Sie seine Typparameter explizit in spitzen Klammern (<type-parameter>) deklarieren.You can also make a function generic by explicitly declaring its type parameters in angle brackets (<type-parameter>). Dies wird im folgenden Code veranschaulicht.The following code illustrates this.

let function2<'T> x y =
    printfn "%A, %A" x y

Verwenden von generischen KonstruktenUsing Generic Constructs

Wenn Sie generische Funktionen oder Methoden verwenden, müssen Sie möglicherweise nicht die Typargumente angeben.When you use generic functions or methods, you might not have to specify the type arguments. Der Compiler verwendet den Typrückschluss, um die entsprechenden Typargumente abzuleiten.The compiler uses type inference to infer the appropriate type arguments. Wenn immer noch eine Mehrdeutigkeit vorliegt, können Sie Typargumente in spitzen Klammern angeben und mehrere Typargumente durch Kommas trennen.If there is still an ambiguity, you can supply type arguments in angle brackets, separating multiple type arguments with commas.

Der folgende Code zeigt die Verwendung der Funktionen, die in den vorherigen Abschnitten definiert sind.The following code shows the use of the functions that are defined in the previous sections.

// In this case, the type argument is inferred to be int.
function1 10 20
// In this case, the type argument is float.
function1 10.0 20.0
// Type arguments can be specified, but should only be specified
// if the type parameters are declared explicitly. If specified,
// they have an effect on type inference, so in this example,
// a and b are inferred to have type int.
let function3 a b =
    // The compiler reports a warning:
    function1<int> a b
    // No warning.
    function2<int> a b

Hinweis

Es gibt zwei Möglichkeiten zum Verweisen auf einen generischen Typ anhand des Namens.There are two ways to refer to a generic type by name. Beispielsweise sind list<int> und int list zwei Methoden zum Verweisen auf einen generischen Typ list, der über ein einzelnes Typargument int verfügt.For example, list<int> and int list are two ways to refer to a generic type list that has a single type argument int. Die letztgenannte Form wird konventionell nur mit integrierten F#-Typen verwendet, wie z.B. list und option.The latter form is conventionally used only with built-in F# types such as list and option. Wenn mehrere Typargumente vorhanden sind, verwenden Sie normalerweise die Syntax Dictionary<int, string>, aber Sie können auch die Syntax (int, string) Dictionary verwenden.If there are multiple type arguments, you normally use the syntax Dictionary<int, string> but you can also use the syntax (int, string) Dictionary.

Platzhalter als TypargumenteWildcards as Type Arguments

Um anzugeben, dass ein Typargument vom Compiler abgeleitet werden soll, können Sie den Unterstrich bzw. das Platzhaltersymbol (_) anstatt eines benannten Typarguments verwenden.To specify that a type argument should be inferred by the compiler, you can use the underscore, or wildcard symbol (_), instead of a named type argument. Dies wird im folgenden Code veranschaulicht.This is shown in the following code.

let printSequence (sequence1: Collections.seq<_>) =
   Seq.iter (fun elem -> printf "%s " (elem.ToString())) sequence1

Einschränkungen bei generischen Typen und FunktionenConstraints in Generic Types and Functions

In einer generischen Typ- oder Funktionsdefinition können Sie nur diese Konstrukte verwenden, die bekanntermaßen für den generischen Typparameter verfügbar sind.In a generic type or function definition, you can use only those constructs that are known to be available on the generic type parameter. Dies ist erforderlich, um die Überprüfung von Funktions- und Methodenaufrufen zur Kompilierzeit zu aktivieren.This is required to enable the verification of function and method calls at compile time. Wenn Sie Ihre Typparameter explizit deklarieren, können Sie eine explizite Einschränkung für einen generischen Typparameter anwenden, um den Compiler zu informieren, dass bestimmte Methoden und Funktionen verfügbar sind.If you declare your type parameters explicitly, you can apply an explicit constraint to a generic type parameter to notify the compiler that certain methods and functions are available. Wenn Sie F#-Compiler die generischen Parametertypen ableiten lassen, wird es jedoch die entsprechenden Einschränkungen für Sie bestimmen.However, if you allow the F# compiler to infer your generic parameter types, it will determine the appropriate constraints for you. Weitere Informationen finden Sie unter Einschränkungen.For more information, see Constraints.

Statisch aufgelöste TypparameterStatically Resolved Type Parameters

Es gibt zwei Arten von Typparametern, die in F#-Programmen verwendet werden können.There are two kinds of type parameters that can be used in F# programs. Die Ersten sind generische Typparameter der Art, die in den vorherigen Abschnitten beschrieben werden.The first are generic type parameters of the kind described in the previous sections. Diese erste Art von Typparameter entspricht den generischen Typparametern, die in Sprachen wie Visual Basic und C# verwendet werden.This first kind of type parameter is equivalent to the generic type parameters that are used in languages such as Visual Basic and C#. Eine andere Art von Typparameter ist für F# spezifisch und wird als ein statisch aufgelöster Typparameter bezeichnet.Another kind of type parameter is specific to F# and is referred to as a statically resolved type parameter. Informationen zu diesen Konstrukten finden Sie unter Statisch aufgelöste Typparameter.For information about these constructs, see Statically Resolved Type Parameters.

BeispieleExamples

// A generic function.
// In this example, the generic type parameter 'a makes function3 generic.
let function3 (x : 'a) (y : 'a) =
    printf "%A %A" x y

// A generic record, with the type parameter in angle brackets.
type GR<'a> =
    {
        Field1: 'a;
        Field2: 'a;
    }

// A generic class.
type C<'a>(a : 'a, b : 'a) =
    let z = a
    let y = b
    member this.GenericMethod(x : 'a) =
        printfn "%A %A %A" x y z

// A generic discriminated union.
type U<'a> =
    | Choice1 of 'a
    | Choice2 of 'a * 'a

type Test() =
    // A generic member
    member this.Function1<'a>(x, y) =
        printfn "%A, %A" x y

    // A generic abstract method.
    abstract abstractMethod<'a, 'b> : 'a * 'b -> unit
    override this.abstractMethod<'a, 'b>(x:'a, y:'b) =
         printfn "%A, %A" x y

Siehe auchSee Also

SprachreferenzLanguage Reference

TypenTypes

Statisch aufgelöste TypparameterStatically Resolved Type Parameters

Generika in .NET FrameworkGenerics in the .NET Framework

Automatische VerallgemeinerungAutomatic Generalization

EinschränkungenConstraints