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]); // 5Indexador 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,3El 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,30Por 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]); // 40Resolució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]); // bResolució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,4Count 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]); // 4Diseñ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,15Comprobació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
IndexyRange. - El patrón implícito: una propiedad
Count/Lengthjunto conSlice(int, int). GetOffset(Length)yGetOffsetAndLength(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
- El tipo Index y el operador ^
- El tipo Range y el operador ..
- Rangos con arrays y cadenas
- Tipos personalizados compatibles con rangos