InicioArticulos y noticiasBases de datosProgramaciónForosInternetServiciosEmail
Tutorial C#
Introduccion a C#
Programacion con C#
Fundamentos de C#
Operadores
Instrucciones
Estrcuturas de control.
Definición de clases
Creación de objetos
Herencia y métodos virtuales
Polimorfismo
Ocultación de miembros
Miembros de tipo
Encapsulación
Espacios de nombres
Importación de espacios de nombres
Espacio de nombres distribuidos
Variables y tipos de datos
Tablas unidimensionales
Tablas multidimensionales
La clase System.Array
Cadenas de texto
Constantes
Orden de inicialización de variables
Métodos
Métodos externos
Constructores
Destructores
Propiedades
Indizadores
Redefinición de operadores
Delegados y eventos
La clase MulticastDelegate
Llamadas asíncronas
Implementación interna de los delegados
Eventos
Estructuras
Boxing y unboxing
Constructores de estructuras
Enumeraciones
Interfaces
Excepciones
Otras instrucciones
Atributos
Definición de nuevos atributos
Lectura de atributos en tiempo de ejecución
Atributos de compilación
Pseudoatributos
Código inseguro
Definición de punteros
Manipulación de punteros
Operadores relacionados con código inseguro
Fijación de variables apuntadas
Novedades de C# 2.0
Genéricos
Tipos parciales
Iteradores
Mejoras en la manipulación de delegados
Tipos anulables
Modificadores de visibilidad de bloques get y set
Clases estáticas
Referencias a espacios de nombres
Supresión temporal de avisos
Atributos condicionales
Incrustación de tablas en estructuras
Modificaciones en el compilador
También puedes ver ...
LinQ To SQL - Un ejemplo sencillo
Problemas en la instalación de Visual Studio 2008-Visual studio web authoring component
Redimiento de VS2008
Insertar en una Tabla usando Linq2SQL (Linq To SQL)
Primeros pasos con Linq2SQL (Linq To SQL)
Novedades Visual Studio 2008 DataSet en 3 capas o MVC
Novedades en C# 3.0 - Primeros pasos con LINQ
Primeras impresiones sobre Visual Studio 2008
Desencriptar Texto y variables con .NET VB y C# (segunda parte)
¿Que son IPCChannel o el protocolo IPC en WCF?

Afiliados
La Web del programador
MundoProgramacion


Inicio | Tutorial C# Fundamentos de C#Tutorial C#Instrucciones Versión para imprimir

Operadores

    Un operador en C# es un símbolo formado por uno o más caracteres que permite realizar una determinada operación entre uno o más datos y produce un resultado.

    A continuación se describen cuáles son los operadores incluidos en el lenguaje clasificados según el tipo de operaciones que permiten realizar, aunque hay que tener en cuenta que C# permite la redefinición del significado de la mayoría de los operadores según el tipo de dato sobre el que se apliquen,  por lo que lo que aquí se cuenta se corresponde con los usos más comunes de los mismos:

  • Operaciones aritméticas: Los operadores aritméticos incluidos en C# son los típicos de suma (+), resta (-), producto (*), división (/) y módulo (%) También se incluyen operadores de “menos unario” () y “más unario” (+)

    Relacionados con las operaciones aritméticas se encuentran un par de operadores llamados checked y unchecked que permiten controlar si se desea detectar los desbordamientos que puedan producirse si al realizar este tipo de  operaciones el resultado es superior a la capacidad del tipo de datos de sus operandos. Estos operadores se usan así:


checked
(
<expresiónAritmética>)

unchecked(<expresiónAritmética>)

Ambos operadores calculan el resultado de <expresiónAritmética> y lo devuelven si durante el cálculo no se produce ningún desbordamiento. Sin embargo, en caso de que haya desbordamiento cada uno actúa de una forma distinta: checked provoca un error de compilación si <expresiónAritmética> es una expresión constante y una excepción System.OverflowException si no lo es, mientras que unchecked devuelve el resultado de la expresión aritmética truncado para que quepa en el tamaño esperado.

Por defecto, en ausencia de los operadores checked y unchecked lo que se hace es evaluar las operaciones aritméticas entre datos constantes como si se les aplicase checked y las operaciones entre datos no constantes como si se les hubiese aplicado unchecked.

  • Operaciones lógicas: Se incluyen operadores que permiten realizar las operaciones lógicas típicas: “and” (&& y &), “or” (|| y |), “not” (!) y “xor” (^)

Los operadores && y || se diferencia de & y | en que los primeros realizan evaluación perezosa y los segundos no. La evaluación perezosa consiste en que si el resultado de evaluar el primer operando permite deducir el resultado de la operación, entonces no se evalúa el segundo y se devuelve dicho resultado directamente, mientras que la evaluación no perezosa consiste en evaluar siempre ambos operandos. Es decir, si el primer operando de una operación && es falso se devuelve false directamente, sin evaluar el segundo; y si el primer operando de una || es cierto se devuelve true directamente, sin evaluar el otro.

  • Operaciones relacionales: Se han incluido los tradicionales operadores de igualdad (==), desigualdad (!=), “mayor que” (>), “menor que” (<), “mayor o igual que” (>=) y “menor o igual que” (<=)

  • Operaciones de manipulación de bits: Se han incluido operadores que permiten realizar a nivel de bits operaciones “and” (&), “or” (|), “not” (~), “xor” (^), desplazamiento a izquierda (<<) y desplazamiento a  derecha (>>) El operador << desplaza a izquierda rellenando con ceros, mientras que el tipo de relleno realizado por >> depende del tipo de dato sobre el que se aplica: si es un dato con signo mantiene el signo, y en caso contrario rellena con ceros.

  • Operaciones de asignación: Para realizar asignaciones se usa en C# el operador =, operador que además de realizar la asignación que se le solicita devuelve el valor asignado.  Por ejemplo, la expresión a = b asigna a la variable a el valor de la variable b y devuelve dicho valor, mientras que la expresión c = a = b asigna a las variables c y a el valor de b (el operador = es asociativo por la derecha)

También se han incluido operadores de asignación compuestos que permiten ahorrar tecleo a  la hora de realizar asignaciones tan comunes como:


 temperatura = temperatura + 15;   // Sin usar asignación compuesta  
 temperatura += 15;                // Usando asignación compuesta

Las dos líneas anteriores son equivalentes, pues el operador compuesto += asigna       a su primer operando el valor que tenía más el de su segundo operando (o sea, le suma el segundo operando) Como se ve, permite compactar bastante el código.

Aparte del operador de asignación compuesto +=, también se ofrecen operadores de asignación compuestos para la mayoría de los operadores binarios ya vistos. Estos son: +=, -=, *=, /=, %=, &=, |=, ^=, <<= y >>=. Nótese que no hay versiones compuestas para los operadores binarios && y ||.

Otros dos operadores de asignación incluidos son los de incremento(++) y decremento (--) Estos operadores permiten, respectivamente, aumentar y disminuir en una unidad el valor de la variable sobre el que se aplican. Así, estas líneas de código son equivalentes:


 temperatura = temperatura+1;//Sin usar asignación compuesta ni incremento
 temperatura += 1;           //Usando asignación compuesta
 temperatura++;              //Usando incremento
           
Si el operador ++ se coloca tras el nombre de la variable (como en el ejemplo) devuelve el valor de la variable antes de incrementarla, mientras que si se coloca antes, devuelve el valor de ésta tras incrementarla; y lo mismo ocurre con el operador --. Por ejemplo:


 c = b++; // Se asigna a c el valor de b y luego se incrementa b
 c = ++b; // Se incrementa el valor de b y luego se asigna a c

La ventaja de usar los operadores ++ y -- es que en muchas máquinas son más eficientes que el resto de formas de realizar sumas o restas de una unidad, pues el compilador puede traducirlos en una única instrucción en código máquina[5].        

  • Operaciones con cadenas: Para realizar operaciones de concatenación de cadenas se puede usar el mismo operador que para realizar sumas, ya que en C# se ha redefinido su significado para que cuando se aplique entre operandos que sean cadenas o que sean una cadena y un carácter lo que haga sea concatenarlos. Por ejemplo, ?Hola?+? mundo? devuelve ?Hola mundo?, y ?Hola mund? + 'o' también.

  • Operaciones de acceso a tablas: Una tabla es un conjunto de ordenado de objetos de tamaño fijo. Para acceder a cualquier elemento de este conjunto se aplica el operador postfijo [] sobre la tabla para indicar entre corchetes la posición que ocupa el objeto al que se desea acceder dentro del conjunto. Es decir, este operador se usa así:

                        [<posiciónElemento>]

Un ejemplo de su uso en el que se asigna al elemento que ocupa la posición 3 en una tabla de nombre tablaPrueba el valor del elemento que ocupa la posición 18 de dicha tabla es el siguiente:

 tablaPrueba[3] = tablaPrueba[18];

Las tablas se estudian detenidamente más adelante

  • Operador condicional: Es el único operador incluido en C# que toma 3 operandos, y se usa así:


<condición> ? <expresión1> : <expresión2>

El significado del operando es el siguiente: se evalúa <condición> Si es cierta se devuelve el resultado de evaluar <expresión1>, y si es falsa se devuelve el resultado de evaluar <condición2>. Un ejemplo de su uso es:


b = (a>0)? a : 0; // Suponemos a y b de tipos enteros
                   

En este ejemplo, si el valor de la variable a es superior a 0 se asignará a b el valor de a, mientras que en caso contrario el valor que se le asignará será 0.

Hay que tener en cuenta que este operador es asociativo por la derecha, por lo que una expresión como a?b:c?d:e es equivalente a a?b:(c?d:e)

No hay que confundir este operador con la instrucción condicional if que se tratará en el Tema 8:Instrucciones, pues aunque su utilidad es similar al de ésta,  ? devuelve  un valor e if no.

  • Operaciones de delegados: Un delegado es un objeto que puede almacenar en referencias a uno o más métodos y a través del cual es posible llamar a estos métodos. Para añadir objetos a un delegado se usan los operadores + y +=, mientras que para quitárselos se usan los operadores y -=. Estos conceptos se estudiarán detalladamente en su correspondiente tema.

  • Operaciones de acceso a objetos: Para acceder a los miembros de un objeto se usa el operador ., cuya sintaxis es:


<objeto>.<miembro>

Si a es un objeto, ejemplos de cómo llamar a diferentes miembros suyos son:


 a.b = 2;  // Asignamos a su propiedad a el valor 2
 a.f();    // Llamamos a su método f()
 a.g(2); // Llamamos a su método g() pasándole como parámetro
// el valor entero 2
                            

No se preocupe si no conoce los conceptos de métodos, propiedades, eventos y delegados en los que se basa este ejemplo, pues se explican detalladamente en temas posteriores.

  • Operaciones con punteros: Un puntero es una variable que almacena una referencia a una dirección de memoria. Para obtener la dirección de memoria de un objeto se usa el operador &, para acceder al contenido de la dirección de memoria almacenada en un puntero se usa el operador *, para acceder a un miembro de un objeto cuya dirección se almacena en un puntero se usa ->, y para referenciar una dirección de memoria de forma relativa a un puntero se le aplica el operador [] de la forma puntero[desplazamiento]. Todos estos conceptos se explicarán más a fondo en el Tema 18: Código inseguro.

  • Operaciones de obtención de información sobre tipos: De todos los operadores que nos permiten obtener información sobre tipos de datos el más importante es typeof, cuya forma de uso es:


typeof
(
<nombreTipo>)

Este operador devuelve un objeto de tipo System.Type con información sobre el tipo de nombre <nombreTipo> que podremos consultar a través de los miembros  ofrecidos por dicho objeto. Esta información incluye detalles tales como cuáles son sus miembros, cuál es su tipo padre o a qué espacio de nombres pertenece.

Si lo que queremos es determinar si una determinada expresión es de un tipo u otro, entonces el operador a usar es is, cuya sintaxis es la siguiente:


<expresión> is <nombreTipo>

El significado de este operador es el siguiente: se evalúa <expresión>. Si el resultado de ésta es del tipo cuyo nombre se indica en <nombreTipo> se devuelve true; y si no, se devuelve false. Como se verá en el Tema 5: Clases, este operador suele usarse en métodos polimórficos.

Finalmente, C# incorpora un tercer operador que permite obtener información sobre un tipo de dato: sizeof Este operador permite obtener el número de bytes que ocuparán en memoria los objetos de un tipo, y se usa así:


sizeof
(
<nombreTipo>)

sizeof sólo puede usarse dentro de código inseguro, que por ahora basta considerar que son zonas de código donde es posible usar punteros. No será hasta el Tema 18: Código inseguro cuando lo trataremos en profundidad.

Además, sizeof sólo se puede aplicar sobre nombres de tipos de datos cuyos objetos se puedan almacenar directamente en pila. Es decir, que sean estructuras (se verán en el Tema 13) o tipos enumerados (se verán en el Tema 14)

  • Operaciones de creación de objetos: El operador más típicamente usado para crear objetos es new, que se usa así:


new <nombreTipo>(<parametros>)

Este operador crea un objeto de <nombreTipo> pasándole a su método constructor los parámetros indicados en <parámetros> y devuelve una referencia al mismo. En función del tipo y número de estos parámetros se llamará a uno u otro de los constructores del objeto. Así, suponiendo que a1 y a2 sean variables de tipo Avión, ejemplos de uso del operador new  son:


 Avión a1 = new Avión(); // Se llama al constructor sin parámetros
// de Avión
 Avión a2 = new Avión("Caza");  // Se llama al constructor de Avión que
                                // toma como parámetro una cadena

En caso de que el tipo del que se haya solicitado la creación del objeto sea una clase, éste se creará en memoria dinámica, y lo que new devolverá será una referencia a la dirección de pila donde se almacena una referencia a la dirección del objeto en memoria dinámica. Sin embargo, si el objeto a crear pertenece a una estructura o a un tipo enumerado, entonces éste se creará directamente en la pila y la referencia devuelta por el new se referirá directamente al objeto creado. Por estas razones, a las clases se les conoce como tipos referencia ya que de sus objetos en pila sólo se almacena una referencia a la dirección de memoria dinámica donde verdaderamente se encuentran; mientras que a las estructuras y tipos enumerados se les conoce como tipos valor ya sus objetos se almacenan directamente en pila.

C#  proporciona otro operador que también nos permite crear objetos. Éste es stackalloc, y se usa así:


stackalloc
<nombreTipo>[<nElementos>]

Este operador lo que hace es crear en pila una tabla de tantos elementos de tipo <nombreTipo> como indique <nElementos> y devolver la dirección de memoria en que ésta ha sido creada. Por ejemplo:


int
* p = stackalloc[100]; // p apunta a una tabla de 100 enteros.

stackalloc
sólo puede usarse para inicializar punteros a objetos de tipos valor declarados como variables locales.

  • Operaciones de conversión: Para convertir unos objetos en otros se utiliza el operador de conversión, que no consiste más que en preceder la expresión a convertir del nombre entre paréntesis del tipo al que se desea convertir el resultado de evaluarla. Por ejemplo, si l es una variable de tipo long y se desea almacenar su valor dentro de una variable de tipo int llamada i, habría que convertir previamente su valor a tipo int así:

 
i = (int) l;  // Asignamos a i el resultado de convertir el valor de l
// a tipo int

Los tipos int y long están predefinidos en C# y permite almacenar valores enteros con signo. La capacidad de int es de 32 bits, mientras que la de long es de 64 bits. Por tanto, a no ser que hagamos uso del operador de conversión, el compilador no nos dejará hacer la asignación, ya que al ser mayor la capacidad de los long, no todo valor que se pueda almacenar en un long tiene porqué poderse almacenar en un int. Es decir, no es válido:


i = l; //ERROR: El valor de l no tiene porqué caber en i

Esta restricción en la asignación la impone el compilador debido a que sin ella podrían producirse errores muy difíciles de detectar ante truncamientos no esperados debido al que el valor de la variable fuente es superior a la capacidad de la variable destino.

Existe otro operador que permite realizar operaciones de conversión de forma muy similar al ya visto. Éste es el operador as, que se usa así: 


<expresión> as <tipoDestino>

Lo que hace es devolver el resultado de convertir el resultado de evaluar <expresión> al tipo indicado en <tipoDestino> Por ejemplo, para almacenar en una variable p el resultado de convertir un objeto t a tipo tipo Persona se haría:


p = t as Persona;

Las únicas diferencias entre usar uno u otro operador de conversión son:

    •  as sólo es aplicable a tipos referencia y sólo a aquellos casos en que existan conversiones predefinidas en el lenguaje. Como se verá más adelante, esto sólo incluye conversiones entre un tipo y tipos padres suyos y entre  un tipo y tipos hijos suyos.

Una consecuencia de esto es que el programador puede definir cómo hacer conversiones de tipos por él definidos y otros mediante el operador (), pero no mediante as.Esto se debe a que as únicamente indica que se desea que una referencia a un objeto en memoria dinámica se trate como si el objeto fuese de otro tipo, pero no implica conversión ninguna. Sin embargo, () sí que implica conversión si el <tipoDestino> no es compatible con el tipo del objeto referenciado. Obviamente, el operador se aplicará  mucho más rápido en los casos donde no sea necesario convertir.

    • En caso de que se solicite hacer una conversión inválida as devuelve null mientras que () produce una excepción System.InvalidCastException.


Inicio | Tutorial C# Fundamentos de C#Tutorial C#Instrucciones Versión para imprimir Foros de consulta


Añadir comentario ... Para preguntar utiliza los foros
Autor:

Título:


Para preguntar utiliza los foros.



Inicio | Tutorial C# Fundamentos de C#Tutorial C#Instrucciones Versión para imprimir

Operadores
Autor: José Antonio González Seco
Visitas: 13049 Fecha de publicación: 03/10/2006
José Antonio es experto en tecnologias Microsoft. Imparte cursos y conferencias en congresos sobre C# y .NET en Universidades de toda España (Sevilla, Barcelona, San Sebastián, Valencia, Oviedo, etc.) en representación de grandes empresas como Microsoft.



devjoker  Lo más nuevo ... Donde se habla ... 
03/04/2008 LINQ con métodos Extensores y expresiones lambda    forma parte de...Métodos extensores
03/04/2008 Métodos Extensores: SELECT    forma parte de...Métodos extensores
03/04/2008 Almacenamiento (1)    forma parte de...Tutorial de Sistemas Informaticos
28/03/2008 Mapa de configuracion de WCF
28/03/2008 LinQ To SQL - Un ejemplo sencillo
25/03/2008 Sitios Web de ejemplo ASP.NET
22/03/2008 Problemas al conectar a redes wifi con Windows Vista
19/03/2008 Service Pack 1 de Windows Vista

Útimos temas recibidos en los foros ...
Insertar datos en un grid manualmente por flakita ... [C#] 0 09/04/2008
ayuda con un select por Manu ... [mySQL] 8 25/07/2007
CHASIS DE UN PC CUALQUIERA por carolina ... [WIN 98/NT/2000/XP] 5 23/11/2006
Q PASA JENTE por torrichi ... [Java] 2 25/03/2008
LLINQ to SQL por Javier ... [C#] 1 09/04/2008
Agendar tarea por dia pero q pueda ser a diferente hora cada dia por Orlan ... [C#] 1 09/04/2008
Ventana Popup por Maurito22 ... [ASP.NET] 1 31/03/2008
No se puede abrir el archivo fisico por ron ... [C#] 1 07/04/2008
Data report visual basic 6.0 impresion con codigo por Andres ... [Visual Basic 6.0] 8 19/11/2007
Como abrir un docuemto de word desde c# y leer las palabras para luego enviar a access por llen ... [C#] 1 08/04/2008
sentencia for por .net ... [C#] 2 08/04/2008
Leer campos blob de oracle en lenguaje visual basic por janito ... [Visual Basic 6.0] 0 08/04/2008

Access CGI JSP ORACLE UNIX
Actualidad HTML/DHTML/XHTML LINUX PHP Visual Basic .NET
ASP ISAPI MS DOS Power Builder Visual Basic 6.0
ASP.NET Java mySQL SQL WIN 98/NT/2000/XP
C# JavaScript Opinion SQL Server

devjoker  Te recomendamos además ...
21/07/2006 Funciones integradas de PL/SQL    forma parte de...Tutorial PL/SQL
28/08/2006 Ubuntu en VmWare con VMware Tools
22/10/2005 Insertar datos. INSERT    forma parte de...Tutorial SQL
24/05/2007 Tipos de datos en Transact SQL    forma parte de...Tutorial de Transact SQL
12/01/2006 Programación con PL/SQL    forma parte de...Tutorial PL/SQL
16/10/2006 Delegados y eventos    forma parte de...Tutorial C#
14/05/2007 Fundamentos de Transact SQL    forma parte de...Tutorial de Transact SQL
31/03/2006 Operadores en PL/SQL    forma parte de...Tutorial PL/SQL
11/09/2006 Trabajar con datos de tipo BLOB en ORACLE
12/01/2006 Introducción a PLSQL    forma parte de...Tutorial PL/SQL

 

Encuesta
¿Cual es tu lenguaje de programación favorito?
[Ver] [Votar]