0Pricing
C# Academy · Lección

Tipos personalizados compatibles con rangos

Añada compatibilidad con Index y Range a sus tipos.

Tipos personalizados compatibles con rangos es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.

Dos formas de admitir índices y rangos

Sus propios tipos pueden admitir la sintaxis de Index y Range. Hay dos opciones: proporcionar indexadores explícitos o proporcionar una propiedad Length/Count junto con un método Slice.

Indexador explícito de Index

Añada un indexador que acepte System.Index y el operador ^ funcionará directamente con su tipo.

using System;

class Deck {
    private int[] cards = { 1, 2, 3, 4, 5 };
    public int this[Index i] => cards[i];
}

var d = new Deck();
Console.WriteLine(d[^1]); // 5

Indexador explícito de Range

Para admitir la segmentación con .., añada un indexador que acepte System.Range y devuelva el tipo de segmento que desee.

using System;

class Deck {
    private int[] cards = { 1, 2, 3, 4, 5 };
    public int[] this[Range r] => cards[r];
}

var d = new Deck();
Console.WriteLine(string.Join(",", d[1..3])); // 2,3

El patrón Length + Slice

El compilador también puede generar automáticamente la compatibilidad con rangos si su tipo tiene una propiedad Count o Length y un método Slice(int start, int length).

Implementación del patrón

Aquí, un búfer personalizado expone Length y Slice. El compilador reescribe buf[1..3] como buf.Slice(1, 2) automáticamente.

using System;

class Buffer {
    private int[] data = { 10, 20, 30, 40 };
    public int Length => data.Length;
    public int this[int i] => data[i];
    public int[] Slice(int start, int length) {
        var result = new int[length];
        Array.Copy(data, start, result, 0, length);
        return result;
    }
}

var buf = new Buffer();
Console.WriteLine(string.Join(",", buf[1..3])); // 20,30

Por qué es importante Length

La propiedad Length (o Count) permite al compilador resolver índices desde el final como ^1 en su tipo. Sin ella, ^ no se puede traducir.

using System;

class Buffer {
    private int[] data = { 10, 20, 30, 40 };
    public int Length => data.Length;
    public int this[Index i] => data[i.GetOffset(Length)];
}

var buf = new Buffer();
Console.WriteLine(buf[^1]); // 40

Resolución manual de un índice

Dentro de un indexador de Index, llame a i.GetOffset(Length) para convertir un índice que posiblemente proceda del final en un desplazamiento simple.

using System;

class Ring {
    private string[] items = { "a", "b", "c" };
    public int Length => items.Length;
    public string this[Index i] {
        get {
            int offset = i.GetOffset(Length);
            return items[offset];
        }
    }
}

var r = new Ring();
Console.WriteLine(r[^2]); // b

Resolución manual de un rango

En un indexador de Range, r.GetOffsetAndLength(Length) le proporciona tanto el inicio como la cantidad que debe copiar.

using System;

class Ring {
    private int[] items = { 1, 2, 3, 4, 5 };
    public int Length => items.Length;
    public int[] this[Range r] {
        get {
            var (start, len) = r.GetOffsetAndLength(Length);
            var slice = new int[len];
            Array.Copy(items, start, slice, 0, len);
            return slice;
        }
    }
}

var r = new Ring();
Console.WriteLine(string.Join(",", r[^3..^1])); // 3,4

Count frente a Length

El patrón acepta cualquiera de los dos nombres: los arrays y spans usan Length; List<T> usa Count. Cualquiera de las dos propiedades satisface al compilador.

using System;
using System.Collections.Generic;

var list = new List<int> { 1, 2, 3, 4 };
// List<T> has Count, so Index works:
Console.WriteLine(list[^1]); // 4

Diseño de los tipos devueltos por Slice

Decida si su Slice devuelve una copia, como en los arrays, o una vista, como en los spans. Las vistas son más económicas, pero comparten estado mutable; documente esta decisión.

Un tipo personalizado completo

Este Sequence admite tanto ^ como .. mediante indexadores explícitos y una propiedad Length.

using System;

class Sequence {
    private int[] data;
    public Sequence(int[] d) => data = d;
    public int Length => data.Length;
    public int this[Index i] => data[i];
    public int[] this[Range r] => data[r];
}

var s = new Sequence(new[] { 5, 10, 15, 20 });
Console.WriteLine(s[^1]);                       // 20
Console.WriteLine(string.Join(",", s[1..^1]));  // 10,15

Comprobación rápida

Confirme qué permite usar la sintaxis de rangos en un tipo personalizado.

Resumen

Ha aprendido dos formas de añadir compatibilidad con Index/Range a sus tipos.

  • Indexadores explícitos que aceptan Index y Range.
  • El patrón implícito: una propiedad Count/Length junto con Slice(int, int).
  • GetOffset(Length) y GetOffsetAndLength(Length) resuelven posiciones desde el final.

Preguntas frecuentes

¿La lección «Tipos personalizados compatibles con rangos» es gratis?

Sí — el texto completo de «Tipos personalizados compatibles con rangos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Tipos personalizados compatibles con rangos»?

Añada compatibilidad con Index y Range a sus tipos. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar C# Academy?

No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Tipos personalizados compatibles con rangos»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de C# Academy?

Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. El tipo Index y el operador ^
  2. El tipo Range y el operador ..
  3. Rangos con arrays y cadenas
  4. Tipos personalizados compatibles con rangos
← Volver a C# Academy