Grundlegendes zu C#-Kovarianz und -Kontravarianz (4) Arrays

Grundlegendes zu C#-Kovarianz und -Kontravarianz (4) Arrays

Grundlegendes zu C#-Kovarianz und -Konreavarianz:

  • Grundlegendes zu C#-Kovarianz und -Kontravarianz (1) Delegaten
  • C#-Kovarianz- und -Kontravarianzschnittstellen (2) verstehen
  • Kovarianz und Kontravarianz in C# verstehen (3) Beispiele
  • Grundlegendes zu C#-Kovarianz- und -Kontravarianz-(4)-Arrays
  • Verstehen von C#-Kovarianz und -Kontravarianz (5) Funktionen höherer Ordnung
  • Verstehen von C#-Kovarianz und -Kontravarianz (6) Typisierungsproblemen
  • C#-Kovarianz und -Kontravarianz verstehen (7) CLR
  • Verstehen von C#-Kovarianz und -Kontravarianz (8) Struct und Void

Ein Array T[] kann als IList angezeigt werden. Wie bereits erwähnt, ist T für IList.

unveränderlich

Kovarianz

C# unterstützt unerwartet Kovarianz für Array:

public static partial class Array
{
    public static void Covariance()
    {
        // IList<Base> baseArray = new Base[2];
        Base[] baseArray = new Base[2];

        // IList<Derived> derivedArray = new Derived[3];
        Derived[] derivedArray = new Derived[2];

        // T of IList<T> is invariant,
        // so logically binding IList<derivedArray> to IList<Base> could not be compiled.
        // But C# compiles it, to be compliant with Java :(
        baseArray = derivedArray; // Array covariance.

        // At runtime, baseArray refers to a Derived array.
        // So A Derived object can be an element of baseArray[0].
        baseArray[0] = new Derived();

        // At runtime, baseArray refers to a Derived array.
        // A Base object "is not a" Derivd object.
        // And ArrayTypeMismatchException is thrown at runtime.
        baseArray[1] = new Base();
    }
}

Der obige Code kann kompiliert werden, löst aber zur Laufzeit ArrayTypeMismatchException aus. In einigen Szenarien kann dies verwirrend sein und Code fehlerhaft machen. Zum Beispiel bei der Verwendung von Array als Parameter:

public static partial class Array
{
    public static void ProcessArray(Base[] array)
    {
        array[0] = new Base(); // ArrayTypeMismatchException.
        }

    public static void CallProcessArray()
    {
        Derived[] array = new Derived[1];
        ProcessArray(array); // Array covariance. Compliable.
    }
}

Wie bereits erwähnt, hat der Werttyp nichts mit Varianzen zu tun, der folgende Code kann nicht kompiliert werden:

public static partial class Array
{
    public static void ValueType()
    {
        object[] objectArray = new object[1];
        int[] int32Array = new int[1];
#if Uncompilable
        // No covariance.
        objectArray = int32Array;
#endif
    }
}

Kommentare

Hier sind einige Kommentare zur Array-Kovarianz:

  • Jonathan Allen sagte:
  • In dem Buch „The Common Language Infrastructure Annotated Standard“ sagte Jim Miller:
  • Rick Byers sagte:
  • Anders Hejlsberg (Chefarchitekt von C#) sagte in diesem Video

Dies ist eine C#-Funktion, die niemals verwendet werden sollte.