Signaturer

En signaturfil innehåller information om offentliga signaturer för en uppsättning F#-programelement, till exempel typer, namnområden och moduler. Den kan användas för att ange tillgängligheten för dessa programelement.

Kommentarer

För varje F#-kodfil kan du ha en signaturfil, som är en fil som har samma namn som kodfilen men med filnamnstillägget .fsi i stället för .fs. Signaturfiler kan också läggas till på kommandoraden för kompilering om du använder kommandoraden direkt. För att skilja mellan kodfiler och signaturfiler kallas kodfiler ibland för implementeringsfiler. I ett projekt ska signaturfilen föregå den associerade kodfilen.

En signaturfil beskriver namnrymder, moduler, typer och medlemmar i motsvarande implementeringsfil. Du använder informationen i en signaturfil för att ange vilka delar av koden i motsvarande implementeringsfil som kan nås från kod utanför implementeringsfilen och vilka delar som är interna i implementeringsfilen. Namnrymder, moduler och typer som ingår i signaturfilen måste vara en delmängd av namnrymderna, modulerna och typerna som ingår i implementeringsfilen. Med vissa undantag som anges senare i det här avsnittet anses de språkelement som inte visas i signaturfilen vara privata för implementeringsfilen. Om ingen signaturfil hittas i projektet eller kommandoraden används standardtillgängligheten.

Mer information om standardtillgänglighet finns i Åtkomstkontroll.

I en signaturfil upprepar du inte definitionen av typerna och implementeringarna av varje metod eller funktion. I stället använder du signaturen för varje metod och funktion, som fungerar som en fullständig specifikation av de funktioner som implementeras av en modul eller ett namnområdesfragment. Syntaxen för en typsignatur är densamma som den som används i abstrakta metoddeklarationer i gränssnitt och abstrakta klasser, och visas också av IntelliSense och av F#-tolken fsi.exe när den visar korrekt kompilerade indata.

Om det inte finns tillräckligt med information i typsignaturen för att ange om en typ är förseglad eller om den är en gränssnittstyp, måste du lägga till ett attribut som anger typens typ i kompilatorn. Attribut som du använder för detta ändamål beskrivs i följande tabell.

Attribut beskrivning
[<Sealed>] För en typ som inte har några abstrakta medlemmar eller som inte bör utökas.
[<Interface>] För en typ som är ett gränssnitt.

Kompilatorn genererar ett fel om attributen inte är konsekventa mellan signaturen och deklarationen i implementeringsfilen.

Använd nyckelordet val för att skapa en signatur för ett värde eller ett funktionsvärde. type Nyckelordet introducerar en typsignatur.

Du kan generera en signaturfil med hjälp av kompilatoralternativet --sig . I allmänhet skriver du inte .fsi-filer manuellt. I stället genererar du .fsi-filer med hjälp av kompilatorn, lägger till dem i projektet, om du har en, och redigerar dem genom att ta bort metoder och funktioner som du inte vill ska vara tillgängliga.

Det finns flera regler för typsignaturer:

  • Skriv förkortningar i en implementeringsfil får inte matcha en typ utan en förkortning i en signaturfil.

  • Poster och diskriminerade fackföreningar måste exponera antingen alla eller inga av sina fält och konstruktorer, och ordningen i signaturen måste matcha ordningen i implementeringsfilen. Klasser kan visa några, alla eller inga av deras fält och metoder i signaturen.

  • Klasser och strukturer som har konstruktorer måste exponera deklarationerna för sina basklasser (deklarationen inherits ). Dessutom måste klasser och strukturer som har konstruktorer exponera alla sina abstrakta metoder och gränssnittsdeklarationer.

  • Gränssnittstyper måste visa alla sina metoder och gränssnitt.

Reglerna för värdesignaturer är följande:

  • Modifierare för hjälpmedel (public, internal, och så vidare) och inline modifierarna och mutable i signaturen måste matcha dem i implementeringen.

  • Antalet generiska typparametrar (antingen implicit härledda eller explicit deklarerade) måste matcha, och typerna och typbegränsningarna i generiska typparametrar måste matcha.

  • Literal Om attributet används måste det visas i både signaturen och implementeringen, och samma literalvärde måste användas för båda.

  • Mönstret för parametrar (även kallat aritet) för signaturer och implementeringar måste vara konsekvent.

  • Om parameternamnen i en signaturfil skiljer sig från motsvarande implementeringsfil används namnet i signaturfilen i stället, vilket kan orsaka problem vid felsökning eller profilering. Om du vill få ett meddelande om sådana matchningar aktiverar du varning 3218 i projektfilen eller när du anropar kompilatorn (se --warnon under Kompilatoralternativ).

I följande kodexempel visas ett exempel på en signaturfil som har namnrymd, modul, funktionsvärde och skriver signaturer tillsammans med lämpliga attribut. Den visar även motsvarande implementeringsfil.

// Module1.fsi

namespace Library1
  module Module1 =
    val function1 : int -> int
    type Type1 =
        new : unit -> Type1
        member method1 : unit -> unit
        member method2 : unit -> unit

    [<Sealed>]
    type Type2 =
        new : unit -> Type2
        member method1 : unit -> unit
        member method2 : unit -> unit

    [<Interface>]
    type InterfaceType1 =
        abstract member method1 : int -> int
        abstract member method2 : string -> unit

Följande kod visar implementeringsfilen.

namespace Library1

module Module1 =

    let function1 x = x + 1


    type Type1() =
        member type1.method1() =
            printfn "type1.method1"
        member type1.method2() =
            printfn "type1.method2"


    [<Sealed>]
    type Type2() =
        member type2.method1() =
            printfn "type2.method1"
        member type2.method2() =
            printfn "type2.method2"

    [<Interface>]
    type InterfaceType1 =
        abstract member method1 : int -> int
        abstract member method2 : string -> unit

Se även