Dela via


Avvikelser från C#-standarden

Det här dokumentet visar inkonsekvenser mellan Roslyn och C#-standarden där de är kända, ordnade efter standardavsnitt.

Conversions

Implicita enumerationskonverteringar från noll

Från §10.2.4:

En implicit uppräkningskonvertering tillåter att en constant_expression (§11.21) med någon heltalstyp och värdet noll konverteras till alla enum_type och till alla nullable_value_type vars underliggande typ är en enum_type.

Roslyn utför implicita uppräkningskonverteringar från konstanta uttryck med typer av float, double och decimal även:

enum SampleEnum
{
    Zero = 0,
    One = 1
}

class EnumConversionTest
{
    const float ConstFloat = 0f;
    const double ConstDouble = 0d;
    const decimal ConstDecimal = 0m;

    static void PermittedConversions()
    {
        SampleEnum floatToEnum = ConstFloat;
        SampleEnum doubleToEnum = ConstDouble;
        SampleEnum decimalToEnum = ConstDecimal;
    }
}

Konverteringar tillåts (korrekt) inte från konstanta uttryck som har en typ av bool, andra uppräkningar eller referenstyper.

Medlemssökning

Från §12.5.1:

  • Efter att ha tagit bort dolda medlemmar bestäms slutligen resultatet av sökningen:
    • Om uppsättningen består av en enskild medlem som inte är en metod är den här medlemmen resultatet av sökningen.
    • Annars, om uppsättningen endast innehåller metoder, är den här gruppen med metoder resultatet av sökningen.
    • Annars är sökningen tvetydig och ett bindningstidsfel inträffar.

Roslyn implementerar i stället en inställning för metoder framför icke-metodsymboler:

var x = I.M; // binds to I1.M (method)
x();

System.Action y = I.M; // binds to I1.M (method)

interface I1 { static void M() { } }
interface I2 { static int M => 0;   }
interface I3 { static int M = 0;   }
interface I : I1, I2, I3 { }
I i = null;
var x = i.M; // binds to I1.M (method)
x();

System.Action y = i.M; // binds to I1.M (method)

interface I1 { void M() { } }
interface I2 { int M => 0;   }
interface I : I1, I2 { }

Antaganden om välkända typer/medlemmar

Kompilatorn kan göra antaganden om formen och beteendet hos välkända typer/medlemmar. Den kanske inte söker efter oväntade begränsningar, Obsolete attribut eller UnmanagedCallersOnly attribut. Den kan utföra vissa optimeringar baserat på förväntningar om att typerna/medlemmarna är väluppfostrade. Obs! Kompilatorn bör förbli motståndskraftig mot välkända typer/medlemmar som saknas.

Partiella gränssnittsmetoder

Partiella gränssnittsmetoder är implicit icke-virtuella, till skillnad från icke-partiella gränssnittsmetoder och andra partiella gränssnittsmedlemstyper, se en relaterad icke-bakåtkompatibel ändring och LDM 2025-04-07.