C# - Entendendo os operadores 'is' e 'as'


 Neste artigo vou apresentar os conceitos relacionados com as palavras chaves 'is' e 'as' mostrando como são usadas e quais as suas diferenças.

As palavras chaves 'is' e 'as' são usadas para realizar a conversão de um tipo de dados em outro tipo , o que também é conhecido como Type Conversion ou Type Casting.

Vamos começar pela definição de 'is' :

A palavra-chave 'is' verifica se um objeto é compatível com um determinado tipo, (a partir do C# 7 testa uma expressão contra um padrão) e o resultado da avaliação é um booleano: true ou false.

Ela faz uma avaliação da compatibilidade de tipo em tempo de execução, e determina se uma instância do objeto ou o resultado de uma expressão pode ser convertido em um tipo especificado.

Sintaxe :   expr is type    Ex:  if (obj is Pessoa){ //...}
 

Onde expr é uma expressão que avalia para uma instância de algum tipo e type é o nome do tipo ao qual o resultado de expr deve ser convertido.

A instrução is é true se expr for não nulo e o objeto resultante da avaliação da expressão pode ser convertido no tipo; Caso contrário, ele é false.

Agora a definição de 'as' :

O operador 'as' tenta converter um objeto para um tipo específico e retorna nulo se a conversão falhar. (Não lança uma exceção)

Você pode usar o operador as para realizar determinados tipos de conversões entre tipos de referência compatíveis ou tipos que permitem valor nulo.

Sintaxe :   expr as type    Ex:  if (obj as Pessoa){ //...}
 

Então à primeira vista não fica muito claro qual a diferença entre 'is' e 'as' então vamos para o código...

Recursos Usados:

Criando o projeto Console

Abra o VS 2017 Community e crie um projeto do tipo Console Application com o nome CShp_Casting.

A seguir inclua o código abaixo no projeto :

using System;
using static System.Console;
namespace CShp_Casting
{
    class Teste
    {
        public Teste()
        {
            Console.WriteLine("Ola, de Teste...");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            // Cria um objeto do tipo object
            object obj = new object(); 	  	
            WriteLine(obj);
            // Será lançada um runtime InvalidCastException :
            // "Unable to cast object of type 'System.Object' to type 'Teste'"          
            Teste teste = (Teste)obj;
            if (teste != null)
            {
                WriteLine("Objeto teste não contém um valor null");
            }
            else
            {
                WriteLine("Objeto teste contém um valor null");
            }
            ReadKey();
        }
    }
}    

Neste exemplo temos uma classe Teste e uma classe Program.

No método Main da classe Program criamos um objeto do tipo object e a seguir fizemos uma conversão do tipo object para o tipo Teste :  Teste teste = (Teste)obj;

Esta conversão é incompatível e lança uma exceção em tempo de execução conforme mostra a figura ao lado.

Portanto, para evitar exceções em tempo de execução, a palavra-chave 'as' pode ser usada.

Se a conversão for incompatível, ele retornará um valor nulo em vez de uma exceção. Isso é muito útil para salvar nosso programa de falhas/exceções.

A sintaxe usada é :  expressão as tipodados

Assim, no exemplo acima podemos alterar o código onde estamos fazendo a conversão para :
Teste teste = obj as Teste;

...      
    class Program
    {
        static void Main(string[] args)
        {
            // Cria um objeto do tipo object
            object obj = new object();
            WriteLine(obj);
            // Será lançada um runtime InvalidCastException :
            // "Unable to cast object of type 'System.Object' to type 'Teste'"  
            //Teste teste = (Teste)obj;
            Teste teste = obj as Teste;
            if (teste != null)
            {
                WriteLine("Objeto teste não contém um valor null");
            }
            else
            {
                WriteLine("Objeto teste contém um valor null");
            }
            ReadKey();
        }
    }
...

Observe que agora o resultado obtido indica que foi atribuido o valor null ao objeto resultante visto que a conversão é incompatível.

Vamos agora aplicar o operador 'is' :

class Program
    {
        static void Main(string[] args)
        {
            // Cria um objeto do tipo object
            object obj = new object();
            WriteLine(obj);
            // Será lançada um runtime InvalidCastException :
            // "Unable to cast object of type 'System.Object' to type 'Teste'"  
            //Teste teste = (Teste)obj;
            //Teste teste = obj as Teste;
            Boolean resultado = obj is Teste;
            if (resultado == true)
            {
                WriteLine("obj pode ser convertido em Teste");
            }
            else
            {
                WriteLine("obj é imcompatível com Teste");
            }
            ReadKey();
        }

 

 
 

A palavra-chave 'is' avalia a compatibilidade entre os tipos em tempo de execução  e pode checar a compatibilidade de tipos por valor (int, double, char, bool) e tipos definidos pelo usuário.

Assim, temos que os operadores 'is' e 'as' são usados para realizar a conversão entre tipos ou casting.

O operador 'as' é semelhante a uma conversão , mas retorna nulo em vez de uma exceção se ele a conversão falhar.

Já o operador 'is' é usado para verificar se um objeto é compatível com um determinado tipo. Geralmente ele é usado nas declarações If.

Até o próximo artigo C#.

(Disse Jesus) - Eu sou a videira verdadeira, e meu Pai é o lavrador.
Toda a vara em mim, que não dá fruto, a tira; e limpa toda aquela que dá fruto, para que dê mais fruto.
João 15:1,2

Referências:


José Carlos Macoratti