is nos dice si un objeto es de un tipo determinado, y desde C# 7 nos deja incluso declarar la variable directamente en la comprobación.
if (obj is string texto)
{
Console.WriteLine(texto.ToUpper());
}
De esta forma, la verificación y el cast se hacen en una sola línea, clara y segura.
El otro operador, as, va un paso más allá: intenta convertir el objeto y, si no puede, devuelve null en lugar de lanzar una excepción. Ideal para esos casos donde la conversión no es obligatoria, pero sí útil si ocurre:
var texto = obj as string;
if (texto != null)
{
Console.WriteLine(texto.Length);
}
Con estos dos, en C# rara vez tenemos que hacer casts inseguros, y eso se agradece.
Ahora, en el mundo Java siempre hemos tenido a instanceof, que durante años fue… digamos… más básico: verificaba el tipo, pero luego había que castear manualmente:
if (obj instanceof String) {
String texto = (String) obj;
System.out.println(texto.toUpperCase());
}
Esto cambió en Java 14, cuando instanceof adoptó pattern matching. Ahora podemos escribir:
if (obj instanceof String texto) {
System.out.println(texto.toUpperCase());
}
Sí, muy similar a lo que C# ya hacía.
Y con Java 21 llegó la verdadera vuelta de tuerca: pattern matching dentro de switch. Esto no solo ahorra código, sino que hace más expresivas estructuras de control que antes eran un desfile de if/else.
switch (obj) {
case String s -> System.out.println("Cadena: " + s.toUpperCase());
case Integer i -> System.out.println("Entero: " + (i * 2));
default -> System.out.println("Otro tipo");
}
Así que hoy, si trabajás en C#, tenés en is y as dos herramientas muy potentes para escribir código seguro y legible. Y si venís de Java, sabé que instanceof ya no es el operador limitado de antes: está alcanzando la versatilidad de C#, y con switch incluso ofrece caminos nuevos para organizar la lógica.
En ambos lenguajes, dominar estas técnicas significa escribir código más limpio, menos propenso a errores y, sobre todo, más agradable de mantener.