You are on page 1of 148

.NET 2 C# .

NET

Introduccin al lenguaje C# y .NET Framework


C# es un lenguaje orientado a objetos elegante y con seguridad de tipos que permite a los desarrolladores crear una amplia gama de aplicaciones slidas y seguras que se ejecutan en .NET Framework. Puede utilizar este lenguaje para crear aplicaciones cliente para Windows tradicionales, servicios Web XML, componentes distribuidos, aplicaciones cliente-servidor, aplicaciones de base de datos, y muchas tareas ms. Microsoft Visual C# 2005 proporciona un editor de cdigo avanzado, diseadores de interfaz de usuario prcticos, un depurador integrado y muchas otras herramientas para facilitar un rpido desarrollo de la aplicacin basado en la versin 2.0 del lenguaje C# y en .NET Framework.

Nota

La documentacin de Visual C# supone que se conocen los conceptos bsicos de programacin. Si es un principiante en la materia, puede explorar Visual C# Express, que est disponible en el Web. Tambin puede aprovechar cualquiera de los excelentes libros y recursos Web sobre C# para obtener conocimientos prcticos de programacin.

Lenguaje C#
La sintaxis de C# es muy expresiva, aunque cuenta con menos de 90 palabras clave; tambin es sencilla y fcil de aprender. La sintaxis de C# basada en signos de llave podr ser reconocida inmediatamente por cualquier persona familiarizada con C, C++ o Java. Los desarrolladores que conocen cualquiera de estos lenguajes pueden empezar a trabajar de forma productiva en C# en un plazo muy breve. La sintaxis de C# simplifica muchas de las complejidades de C++ y, a la vez, ofrece funciones eficaces tales como tipos de valores que aceptan valores NULL, enumeraciones, delegados, mtodos annimos y acceso directo a memoria, que no se encuentran en Java. C# tambin admite mtodos y tipos genricos, que proporcionan mayor rendimiento y seguridad de tipos, e iteradores, que permiten a los implementadores de clases de coleccin definir comportamientos de iteracin personalizados que el cdigo de cliente puede utilizar fcilmente. Como lenguaje orientado a objetos, C# admite los conceptos de encapsulacin, herencia y polimorfismo. Todas las variables y mtodos, incluido el mtodo Main que es el punto de entrada de la aplicacin, se encapsulan dentro de definiciones de clase. Una clase puede heredar directamente de una clase primaria, pero puede implementar cualquier nmero de interfaces. Los mtodos que reemplazan a los mtodos virtuales en una clase primaria requieren la palabra clave override como medio para evitar redefiniciones accidentales. En C#, una estructura es como una clase sencilla; es un tipo asignado en la pila que puede implementar interfaces pero que no admite la herencia. Adems de estos principios bsicos orientados a objetos, C# facilita el desarrollo de componentes de software a travs de varias construcciones de lenguaje innovadoras, entre las que se incluyen:

Firmas de mtodos encapsulados denominadas delegados, que permiten notificaciones de eventos con seguridad de tipos. Propiedades, que actan como descriptores de acceso para variables miembro privadas. Atributos, que proporcionan metadatos declarativos sobre tipos en tiempo de ejecucin. Comentarios en lnea de documentacin XML.

MCT: Luis Dueas

Pag 1 de 148

.NET 2 C# .NET
Si necesita interactuar con otro software de Windows, como objetos COM o archivos DLL nativos de Win32, podr hacerlo en C# mediante un proceso denominado "interoperabilidad". La interoperabilidad permite que los programas de C# realicen prcticamente lo mismo que una aplicacin de C++ nativa. C# admite incluso el uso de punteros y el concepto de cdigo "no seguro" en los casos en que el acceso directo a la memoria es absolutamente crtico. El proceso de generacin de C# es simple en comparacin con el de C y C++, y es ms flexible que en Java. No hay archivos de encabezado independientes, ni se requiere que los mtodos y los tipos se declaren en un orden determinado. Un archivo de cdigo fuente de C# puede definir cualquier nmero de clases, estructuras, interfaces y eventos.

Arquitectura de la plataforma .NET Framework


Los programas de C# se ejecutan en .NET Framework, un componente que forma parte de Windows y que incluye un sistema de ejecucin virtual denominado Common Language Runtime (CLR) y un conjunto unificado de bibliotecas de clases. CLR es la implementacin comercial de Microsoft de Common Language Infrastructure (CLI), norma internacional que constituye la base para crear entornos de ejecucin y desarrollo en los que los lenguajes y las bibliotecas trabajan juntos sin problemas. El cdigo fuente escrito en C# se compila en un lenguaje intermedio (IL) conforme con la especificacin CLI. El cdigo de lenguaje intermedio, junto con recursos tales como mapas de bits y cadenas, se almacena en disco en un archivo ejecutable denominado ensamblado, cuya extensin es .exe o .dll generalmente. Un ensamblado contiene un manifiesto que ofrece informacin sobre los tipos, la versin, la referencia cultural y los requisitos de seguridad del ensamblado. Cuando se ejecuta un programa de C#, el ensamblado se carga en CLR, con lo que se pueden realizar diversas acciones en funcin de la informacin del manifiesto. A continuacin, si se cumplen los requisitos de seguridad, CLR realiza una compilacin Just In Time (JIT) para convertir el cdigo de lenguaje intermedio en instrucciones mquina nativas. CLR tambin proporciona otros servicios relacionados con la recoleccin automtica de elementos no utilizados, el control de excepciones y la administracin de recursos. El cdigo ejecutado por CLR se denomina algunas veces "cdigo administrado", en contraposicin al "cdigo no administrado" que se compila en lenguaje mquina nativo destinado a un sistema especfico. En el diagrama siguiente se muestran las relaciones en tiempo de compilacin y tiempo de ejecucin de los archivos de cdigo fuente de C#, las bibliotecas de clases base, los ensamblados y CLR.

MCT: Luis Dueas

Pag 2 de 148

.NET 2 C# .NET

La interoperabilidad del lenguaje es una funcin clave de .NET Framework. Como el cdigo de lenguaje intermedio generado por el compilador de C# cumple la especificacin de tipos comn (CTS), este cdigo generado en C# puede interactuar con el cdigo generado en las versiones .NET de Visual Basic, Visual C++, Visual J# o cualquiera de los ms de 20 lenguajes conformes con CTS. Un nico ensamblado puede contener varios mdulos escritos en diferentes lenguajes .NET, y los tipos admiten referencias entre s como si estuvieran escritos en el mismo lenguaje. Adems de los servicios en tiempo de ejecucin, .NET Framework tambin incluye una amplia biblioteca de ms de 4.000 clases organizada en espacios de nombres que ofrecen una diversidad de funciones tiles para la entrada y salida de archivos, la manipulacin de cadenas, el anlisis de archivos XML y los controles de formularios Windows Forms. La aplicacin de C# tpica utiliza continuamente la biblioteca de clases de .NET Framework para el tratamiento de las tareas comunes de "infraestructura".

MCT: Luis Dueas

Pag 3 de 148

.NET 2 C# .NET

Lo nuevo en Visual C# 2005


Microsoft Visual C# 2005 incluye nuevas caractersticas en las reas siguientes:

Lenguaje y compilador Editor de cdigo Entorno de desarrollo Documentacin y especificaciones del lenguaje Depuracin

Lenguaje y compilador
El lenguaje de C# admite ahora tipos genricos, iteradores y tipos parciales. La versin ltima del compilador de C# tambin incluye nuevas caractersticas y opciones.

Editor de cdigo
Fragmentos de cdigo Los fragmentos de cdigo aceleran la entrada de construcciones de cdigo comn mediante una plantilla que se puede cumplimentar. Los fragmentos de cdigo se almacenan como archivos XML que se modifican y personalizan con facilidad.

Fragmentos de cdigo (C#) Cmo: Utilizar fragmentos de cdigo (C#) Cmo: Utilizar fragmentos de cdigo envolventes

Refactorizacin Las herramientas de refactorizacin reestructuran automticamente el cdigo fuente, por ejemplo, promocionando variables locales a parmetros o convirtiendo un bloque de cdigo en un mtodo.

Cmo: Promocionar una variable local a parmetro Extraer mtodo Encapsular campo Extraer interfaz Cambiar nombre Quitar parmetros Reordenar parmetros

Entorno de desarrollo
IntelliSense IntelliSense se ha optimizado con estas nuevas caractersticas:

La lista de finalizacin de la Lista de miembros aparece automticamente cuando el cursor retrocede a un operador de mbito que precede a un objeto o cuando deshace la accin de finalizacin.

MCT: Luis Dueas

Pag 4 de 148

.NET 2 C# .NET

Cuando se escribe cdigo de control de errores, la Lista de miembros ayuda a descubrir la excepcin que se debe detectar filtrando los miembros irrelevantes de la lista de finalizacin en una clusula catch.

Cuando sea preciso insertar cdigo normalizado, Generacin automtica de cdigo permite pedir a IntelliSense que inserte el cdigo. IntelliSense est disponible cuando se crean aplicaciones Web.

Diseador de clases El Diseador de clases es un nuevo editor que muestra clases y tipos grficamente, y permite agregar o modificar mtodos. Tambin se pueden utilizar las herramientas de refactorizacin de la ventana Diseador de clases.

Vea Disear y ver clases y tipos.

Herramienta de prueba de objetos La Herramienta de prueba de objetos est diseada para llevar a cabo pruebas sencillas en el nivel de objetos. Permite crear una instancia de un objeto y llamar a sus mtodos.

Vea Herramienta de prueba de objetos.

Implementacin ClickOnce La implementacin de ClickOnce permite publicar aplicaciones para Windows en un servidor Web o recurso compartido de red con el fin de simplificar la instalacin.

Vea Implementacin ClickOnce.

Soporte de herramientas para ensamblados con nombre seguro Se ha rediseado el cuadro de dilogo Propiedades del proyecto, que ahora incluye compatibilidad para firmar ensamblados.

Vea Propiedades del proyecto.

Asistentes para cdigo Los siguientes asistentes de cdigo estn obsoletos:

Asistente para mtodos de C# Asistente para propiedades de C# Asistente para campos de C# Asistente para indizadores de C#

Documentacin y especificaciones del lenguaje


La documentacin de referencia de C# se ha revisado exhaustivamente para dar una informacin completa sobre cuestiones de uso simples y avanzadas que los desarrolladores se planteen durante la creacin de aplicaciones en C#.

Mejoras de depuracin especficas de C#


Se han agregado caractersticas nuevas, como Editar y continuar, para ayudar al desarrollador de C#.

MCT: Luis Dueas

Pag 5 de 148

.NET 2 C# .NET

Crear la primera aplicacin de C#


Slo lleva un minuto crear una aplicacin de C#. Siga estos pasos para crear un programa que abre una ventana y reacciona al presionar un botn.

Procedimientos
Para crear una aplicacin de C# 1. En el men Archivo, elija Nuevo y, a continuacin, haga clic en Proyecto. 2. Asegrese que la plantilla Aplicacin para Windows est seleccionada; en el campo Name, escriba MyProject, y haga clic en Aceptar. Aparecer un formulario Windows Forms en el diseador de Windows Forms. sta es la interfaz de usuario de la aplicacin. 3. En el men Ver, haga clic en Cuadro de herramientas para ver la lista de controles. 4. Expanda la lista Controles comunes y arrastre el control de etiqueta hacia el formulario. 5. Tambin en la lista del Cuadro de herramientas Controles comunes, arrastre un botn al formulario, junto a la etiqueta. 6. Haga doble clic en el nuevo botn para abrir el Editor de cdigo. Visual C# Express ha insertado un mtodo denominado button1_Click que se ejecuta al hacer clic en el botn. 7. Cambie el mtodo para que se parezca a esto:

private void button1_Click(object sender, EventArgs e) { label1.Text = "Hello, World!"; }


8. Presione F5 para compilar y ejecutar la aplicacin. Cuando haga clic en el botn, aparece un mensaje de texto. Enhorabuena! Acaba de escribir su primera aplicacin de C#.

MCT: Luis Dueas

Pag 6 de 148

.NET 2 C# .NET

Palabras clave de C#
Las palabras clave son identificadores predefinidos reservados que tienen un significado especial para el compilador. No se pueden utilizar como identificadores en un programa a menos que incluyan el carcter @ como prefijo. Por ejemplo, @if es un identificador vlido pero if no, por ser una palabra clave.

abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum

event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace Palabras clave contextuales

new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string

struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while

get value

partial where

set yield

MCT: Luis Dueas

Pag 7 de 148

.NET 2 C# .NET

Tipos
El sistema de tipos de C# contiene las siguientes categoras:

Tipos de valor Tipos de referencia Tipos de puntero

Las variables de los tipos de valor almacenan datos, mientras que los tipos de referencia almacenan referencias a los datos reales. Los tipos de referencia tambin se denominan objetos. Los tipos de puntero slo se pueden utilizar en modo unsafe. Un tipo de valor se puede convertir en un tipo de referencia y de nuevo en un tipo de valor mediante boxing y unboxing. No se puede convertir un tipo de referencia en un tipo de valor, excepto en tipos de valor a los que se les ha aplicado una conversin boxing. Esta seccin tambin presenta void. Los tipos de valor tambin aceptan valores null, por tanto pueden almacenar un estado sin valor de suma.

Tipos de valores
Los tipos de valor consisten en dos categoras principales:

Estructuras Enumeraciones

Las estructuras se dividen en las siguientes categoras:

o o o

Tipos numricos Tipos integrales Tipos de punto flotante decimal bool Estructuras definidas por el usuario. Caractersticas principales de los tipos de valor

Variable que est basada directamente en tipos de valor que contienen valores. La asignacin de una variable de tipo de valor a otra copia el valor contenido. Esto es diferente de la asignacin de variables de tipo de referencia, que copia una referencia en el objeto pero no el propio objeto. Todos los tipos de valor se derivan implcitamente de la clase System.ValueType. A diferencia de los tipos de referencia, no es posible obtener un nuevo tipo de un tipo de valor. No obstante, al igual que los tipos de referencia, las estructuras pueden implementar interfaces. A diferencia de los tipos de referencia, los tipos de valor no pueden incluir el valor null. Sin embargo, la caracterstica tipos que aceptan valores NULL permite asignar null a tipos de valores.

MCT: Luis Dueas

Pag 8 de 148

.NET 2 C# .NET
Cada tipo de valor tiene un constructor implcito predeterminado que inicializa el valor predeterminado de ese tipo. Caractersticas principales de los tipos simples Todos los tipos simples (aquellos que forman parte integral del lenguaje C#) son alias de los tipos del sistema .NET Framework. Por ejemplo, int es un alias de System.Int32. Las expresiones constantes, cuyos operandos son todos constantes de tipos simples, se evalan en tiempo de compilacin. Los tipos simples se pueden inicializar mediante literales. Por ejemplo, 'A' es un literal del tipo char y 2001 es un literal del tipo int. Inicializar tipos de valor Las variables locales de C# se deben inicializar antes de utilizarlas. Por consiguiente, si se declara una variable local sin inicializacin como sta:

int myInt;
no se podr utilizar hasta que se inicialice. La inicializacin se puede realizar mediante la siguiente instruccin:

myInt = new int(); // Invoke default constructor for int type.


que equivale a:

myInt = 0; // Assign an initial value, 0 in this example.


Tambin se puede realizar la declaracin y la inicializacin en la misma instruccin:

int myInt = new int();


O bien

int myInt = 0;
Con el operador new, se realiza una llamada al constructor predeterminado del tipo especfico y se asigna el valor predeterminado a la variable. En el ejemplo anterior, el constructor predeterminado asigna a myInt el valor 0. Con los tipos definidos por el usuario, se utiliza new para invocar el constructor predeterminado. Por ejemplo, la siguiente instruccin invoca el constructor predeterminado de la estructura

Point: Point p = new Point(); // Invoke default constructor for the struct.
Despus de esta llamada, la estructura se considera definitivamente asignada; es decir, todos sus miembros se inicializan con sus valores predeterminados.

struct
Un tipo struct es un tipo de valor que se suele utilizar para encapsular pequeos grupos de variables relacionadas, como las coordenadas de un rectngulo o las caractersticas de un elemento de un inventario. En el ejemplo siguiente se muestra una declaracin de estructura sencilla.

public struct Book { public decimal price; public string title; public string author; }
Comentarios

MCT: Luis Dueas

Pag 9 de 148

.NET 2 C# .NET
Las estructuras tambin pueden contener constructores, constantes, campos, mtodos, propiedades, indizadores, operadores, eventos y tipos anidados, aunque si se requieren estos miembros, se debe considerar la posibilidad de crear una clase en vez de un tipo. Las estructuras pueden implementar una interfaz, pero no pueden heredar de otra estructura. Por esa razn, los miembros de estructura no se pueden declarar como protected.

enum
La palabra clave enum se utiliza para declarar una enumeracin, un tipo distinto que consiste en un conjunto de constantes con nombre denominado lista de enumeradores. Cada tipo de enumeracin tiene un tipo subyacente, que puede ser cualquier tipo integral excepto char. El tipo predeterminado subyacente de los elementos de la enumeracin es int. De forma predeterminada, el primer enumerador tiene el valor 0 y el valor de cada enumerador sucesivo se incrementa en 1. Por ejemplo:

enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri}; En esta enumeracin, Sat es 0, Sun es 1, Mon es 2 y as sucesivamente. Los enumeradores
pueden tener inicializadores que reemplazan a los valores predeterminados. Por ejemplo:

enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};


En esta enumeracin, se obliga a que la secuencia de elementos empiece en 1 en vez de en 0. A una variable de tipo Days se le puede asignar cualquier valor en el intervalo del tipo subyacente; los valores no se limitan a las constantes con nombre. El valor predeterminado de un enum E es el valor producido por la expresin (E)0.

Nota

Un enumerador no puede contener espacio en blanco en su nombre. El tipo subyacente especifica el almacenamiento asignado para cada enumerador. No obstante, se necesita una conversin explcita para convertir un tipo enum a un tipo integral. Por ejemplo, la siguiente instruccin asigna el enumerador Sun a una variable de tipo int utilizando una conversin explcita para convertir de enum a int:

int x = (int)Days.Sun;
Cuando se aplica System.FlagsAttribute a una enumeracin que contiene algunos elementos combinados con una operacin OR bit a bit, se observar que el atributo afecta el comportamiento de enum cuando se utiliza con algunas herramientas. Se pueden observar estos cambios al utilizar herramientas tales como los mtodos de la clase Console, el Evaluador de expresiones, etc. (Vea el ejemplo 3). Programacin slida Asignar valores adicionales a nuevas versiones de enumeraciones o cambiar los valores de los miembros de enumeracin en una nueva versin, puede producir problemas para el cdigo fuente dependiente. Es comn que los valores enum se utilicen en instrucciones switch y, si se han agregado elementos adicionales al tipo enum, la comprobacin de los valores predeterminados puede devolver true de forma inesperada.

MCT: Luis Dueas

Pag 10 de 148

.NET 2 C# .NET
Si otros desarrolladores van a utilizar su cdigo, es importante proporcionar instrucciones sobre cmo su cdigo debe reaccionar si se agregan nuevos elementos a cualquier tipo enum. Ejemplo En este ejemplo, se declara la enumeracin Days. Dos enumeradores se convierten explcitamente en un nmero entero y se asignan a variables de nmero entero.

// keyword_enum.cs // enum initialization: using System; public class EnumTest { enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri}; static void Main() { int x = (int)Days.Sun; int y = (int)Days.Fri; Console.WriteLine("Sun = {0}", x); Console.WriteLine("Fri = {0}", y); } }
Resultados

Sun = 2 Fri = 7
En este ejemplo, la opcin de tipo base se utiliza para declarar un enum cuyos miembros son del tipo long. Observe que a pesar de que el tipo subyacente de la enumeracin es long, los miembros de la enumeracin todava deben convertirse explcitamente al tipo long mediante una conversin de tipos.

// keyword_enum2.cs // Using long enumerators using System; public class EnumTest { enum Range :long {Max = 2147483648L, Min = 255L}; static void Main() { long x = (long)Range.Max; long y = (long)Range.Min; Console.WriteLine("Max = {0}", x); Console.WriteLine("Min = {0}", y); } }
Resultados

Max = 2147483648 Min = 255


El ejemplo de cdigo siguiente ilustra el uso y efecto del atributo System.FlagsAttribute en una declaracin enum.

// enumFlags.cs

MCT: Luis Dueas

Pag 11 de 148

.NET 2 C# .NET
// Using the FlagsAttribute on enumerations. using System; [Flags] public enum CarOptions {SunRoof = 0x01, Spoiler = 0x02, FogLights = 0x04, TintedWindows = 0x08, } class FlagTest { static void Main() { CarOptions options = CarOptions.SunRoof | CarOptions.FogLights; Console.WriteLine(options); Console.WriteLine((int)options); } }
Resultados

SunRoof, FogLights 5
Comentarios Observe que si se quita el inicializador de Sat=1, el resultado ser:

Sun = 1 Fri = 6
Comentarios Observe que si elimina FlagsAttribute, el ejemplo generar lo siguiente:

5 5

Tipos de referencia
Las variables de tipos de referencia, conocidas como objetos, almacenan referencias a los datos reales. Esta seccin presenta las palabras clave siguientes utilizadas para declarar tipos de referencia:

class interface delegate

Esta seccin tambin presenta los siguientes tipos de referencia integrados:

object string

class
Las clases se declaran mediante la palabra clave class, como se muestra en el ejemplo siguiente:

class TestClass { // Methods, properties, fields, events, delegates // and nested classes go here. }
Comentarios

MCT: Luis Dueas

Pag 12 de 148

.NET 2 C# .NET
A diferencia de C++, en C# slo se permite la herencia simple. En otras palabras, una clase puede heredar la implementacin de una sola clase base. Sin embargo, una clase puede implementar ms de una interfaz. La siguiente tabla muestra ejemplos de herencia de clases e implementacin de interfaces:

Herencia

Ejemplo

Ninguna Simple Ninguna, implementa dos interfaces Simple, implementa una interfaz

class ClassA { } class DerivedClass: BaseClass { } class ImplClass: IFace1, IFace2 { } class ImplDerivedClass: BaseClass, IFace1 { }

Los niveles de acceso protected y private slo se permiten en clases anidadas. Una clase puede contener declaraciones de los siguientes miembros:

Constructores Destructores Constantes Campos Mtodos Propiedades Indizadores Operadores Eventos Delegados Clases Interfaces Estructuras Ejemplo

En el siguiente ejemplo se muestra la declaracin de campos de clase, constructores y mtodos. Tambin muestra la creacin de instancias de objetos y la impresin de datos de instancia. En este ejemplo, se declaran dos clases, la clase Kid, que contiene dos campos privados (name y age) y dos mtodos pblicos. La segunda clase, MainClass, se utiliza para contener Main.

// keyword_class.cs // class example using System; class Kid { private int age; private string name;

MCT: Luis Dueas

Pag 13 de 148

.NET 2 C# .NET
// Default constructor: public Kid() { name = "N/A"; } // Constructor: public Kid(string name, int age) { this.name = name; this.age = age; } // Printing method: public void PrintKid() { Console.WriteLine("{0}, {1} years old.", name, age); } } class MainClass { static void Main() { // Create objects // Objects must be created using the new operator: Kid kid1 = new Kid("Craig", 11); Kid kid2 = new Kid("Sally", 10); // Create an object using the default constructor: Kid kid3 = new Kid(); // Display results: Console.Write("Kid #1: "); kid1.PrintKid(); Console.Write("Kid #2: "); kid2.PrintKid(); Console.Write("Kid #3: "); kid3.PrintKid(); } }
Resultados

Kid #1: Craig, 11 years old. Kid #2: Sally, 10 years old. Kid #3: N/A, 0 years old.
Comentarios En el ejemplo anterior, observe que slo se puede obtener acceso a los campos privados (name y

age) a travs de los mtodos pblicos de la clase Kid. Por ejemplo, no es posible imprimir un valor name de la clase kid, desde el mtodo Main, con una instruccin como sta: Console.Write(kid1.name); // Error El acceso a los miembros privados de Kid desde Main slo sera posible si Main fuera un
miembro de la clase.

MCT: Luis Dueas

Pag 14 de 148

.NET 2 C# .NET
Los tipos declarados en una clase sin un modificador de acceso tienen como valor predeterminado private, de modo que los miembros de datos de este ejemplo seguiran siendo private aunque se quite la palabra clave. Por ltimo, observe que, para el objeto creado mediante el constructor predeterminado (kid3), el campo age se inicializ a cero de forma predeterminada.

interface
Una interfaz contiene slo las firmas de mtodos, delegados o eventos. La implementacin de los mtodos se hace en la clase que implementa la interfaz, como se muestra en el ejemplo siguiente:

interface ISampleInterface { void SampleMethod(); } class ImplementationClass : ISampleInterface { // Explicit interface member implementation: void ISampleInterface.SampleMethod() { // Method implementation. } static void Main() { // Declare an interface instance. ISampleInterface obj = new ImplementationClass(); // Call the member. obj.SampleMethod(); } }
Comentarios Una interfaz puede ser miembro de un espacio de nombres o de una clase, y puede contener firmas de los siguientes miembros:

Mtodos Propiedades Indizadores Eventos

Una interfaz puede heredar de una o varias interfaces base. Cuando una lista de tipos base contiene una clase base e interfaces, la clase base debe aparecer primero en la lista. Una clase que implementa una interfaz puede implementar explcitamente miembros de esa interfaz. Slo se puede tener acceso a un miembro explcitamente implementado mediante una instancia de la interfaz, y no mediante una instancia de clase, por ejemplo: Ejemplo

MCT: Luis Dueas

Pag 15 de 148

.NET 2 C# .NET
En el siguiente ejemplo, se muestra la implementacin de una interfaz. En este ejemplo, la interfaz IPoint contiene la declaracin de propiedades, la cual es responsable de establecer y obtener los valores de los campos. La clase Point contiene la implementacin de las propiedades.

// keyword_interface_2.cs // Interface implementation using System; interface IPoint { // Property signatures: int x { get; set; } int y { get; set; } } class Point : IPoint { // Fields: private int _x; private int _y; // Constructor: public Point(int x, int y) { _x = x; _y = y; } // Property implementation: public int x { get { return _x; } set { _x = value; } } public int y { get { return _y; } set { _y = value; } } } class MainClass { static void PrintPoint(IPoint p) { Console.WriteLine("x={0}, y={1}", p.x, p.y); } static void Main() { Point p = new Point(2, 3); Console.Write("My Point: "); PrintPoint(p); } }

MCT: Luis Dueas

Pag 16 de 148

.NET 2 C# .NET
Resultados

My Point: x=2, y=3

delegate
La declaracin de un tipo de delegado se presenta de la siguiente forma:

public delegate void TestDelegate(string message);


La palabra clave delegate se usa para declarar un tipo de referencia, que puede utilizarse para encapsular un mtodo con nombre o annimo. Los delegados son similares a los punteros a funciones de C++, pero son ms seguros y proporcionan mayor seguridad de tipos. Comentarios Los delegados son la base de los eventos. Se pueden crear instancias de un delegado asocindolo a un mtodo con nombre o annimo. Para el uso con mtodos con nombre, se deben crear instancias del delegado con un mtodo que tenga una firma aceptable. Para el uso con mtodos annimos, el delegado y el cdigo que se van a asociar se declaran juntos. En esta seccin se describen las dos formas de crear instancias de delegados.

using System; // Declare delegate -- defines required signature: delegate void SampleDelegate(string message); class MainClass { // Regular method that matches signature: static void SampleDelegateMethod(string message) { Console.WriteLine(message); } static void Main() { // Instantiate delegate with named method: SampleDelegate d1 = SampleDelegateMethod; // Instantiate delegate with anonymous method: SampleDelegate d2 = delegate(string message) { Console.WriteLine(message); }; // Invoke delegate d1: d1("Hello"); // Invoke delegate d2: d2(" World"); } }

MCT: Luis Dueas

Pag 17 de 148

.NET 2 C# .NET

object
El tipo object es un alias de Object en .NET Framework. En el sistema de tipos unificado de C#, todos los tipos (tipos de valor y de referencia predefinidos y definidos por el usuario) se heredan directa o indirectamente de Object. Las variables de tipo object pueden recibir valores de cualquier tipo. Cuando una variable de un tipo de valor se convierte en un objeto, se dice que se le ha aplicado la conversin boxing. Cuando una variable de objeto de tipo se convierte en un tipo de valor, se dice que se le ha aplicado la conversin unboxing. Ejemplo En el siguiente ejemplo se muestra cmo las variables de tipo object pueden aceptar valores de cualquier tipo de datos y cmo pueden utilizar mtodos de Object procedentes de .NET Framework.

// keyword_object.cs using System; class SampleClass { public int i = 10; } class MainClass { static void Main() { object a; a = 1; // an example of boxing Console.WriteLine(a); Console.WriteLine(a.GetType()); Console.WriteLine(a.ToString()); a = new SampleClass(); SampleClass classRef; classRef = (SampleClass)a; Console.WriteLine(classRef.i); } }
Resultados

1 System.Int32 1 10

string
El tipo string representa una cadena de caracteres Unicode. string es un alias para String en .NET Framework. Las cadenas son inmutables: no se puede cambiar el contenido de un objeto de tipo string despus de crearlo. Aunque string es un tipo de referencia, los operadores de igualdad (== y !=) se definen para comparar los valores de objetos string, no las referencias. De esta forma, es ms intuitivo comprobar la igualdad entre cadenas. Por ejemplo:

string a = "hello"; string b = "h"; // Append to contents of 'b' b += "ello"; Console.WriteLine(a == b); Console.WriteLine((object)a == (object)b);

MCT: Luis Dueas

Pag 18 de 148

.NET 2 C# .NET
Esto presenta "True" y, despus, "False" porque el contenido de las cadenas es equivalente, pero

a y b no hacen referencia a la misma instancia de cadena.


El operador + concatena cadenas:

string a = "good " + "morning";


Esto crea un objeto de tipo string que contiene "good morning". El operador [] se puede utilizar para tener acceso a caracteres individuales de un objeto string:

string str = "test"; char x = str[2]; // x = 's';


Los literales de cadena son objetos de tipo string que se pueden escribir de dos formas: entre comillas o entre comillas y precedidos de @. Los literales de cadena se deben encerrar entre comillas ("):

"good morning" // a string literal


Los literales de cadena pueden contener cualquier literal de carcter, incluidas las secuencias de escape:

string a = "\\\u0066\n";
Esta cadena contiene una barra diagonal inversa, la letra f y el carcter de nueva lnea.

Nota El cdigo de escape \udddd (donde dddd es un nmero de cuatro dgitos) representa el carcter Unicode U+dddd. Tambin se reconocen los cdigos de escape Unicode de 8 dgitos: \udddd\udddd. Los literales de cadena entrecomillados y precedidos por @ empiezan con este smbolo y se encierran entre comillas. Por ejemplo:

@"good morning" // a string literal


La ventaja de utilizar la combinacin del signo @ y el entrecomillado es que las secuencias de escape no se procesan, lo que facilita la escritura, por ejemplo, de un nombre de archivo completo:

@"c:\Docs\Source\a.txt" // rather than "c:\\Docs\\Source\\a.txt"


Para incluir comillas tipogrficas en una cadena precedida del smbolo @, escriba las comillas dos veces:

@"""Ahoy!"" cried the captain." // "Ahoy!" cried the captain.


Otro uso del smbolo @ consiste en utilizar identificadores de referencia (/reference) que resulten ser palabras clave de C#. Ejemplo

// keyword_string.cs using System; class TestClass { static void Main() { string a = "\u0068ello "; string b = "world";

MCT: Luis Dueas

Pag 19 de 148

.NET 2 C# .NET
Console.WriteLine( a + b ); Console.WriteLine( a + b == "hello world" ); } }
Resultados

hello world True

void
Cuando se utiliza como tipo de valor devuelto por un mtodo, void especifica que el mtodo no devuelve ningn valor. No se permite utilizar void en una lista de parmetros de un mtodo. Un mtodo que no utiliza parmetros y que no devuelve ningn valor se declara del siguiente modo:

void SampleMethod();
void tambin se utiliza en un contexto no seguro para declarar un puntero a un tipo desconocido. void es un alias para el tipo System.Void de .NET Framework.

MCT: Luis Dueas

Pag 20 de 148

.NET 2 C# .NET

Tablas de referencia de tipos


Las siguientes tablas de referencia de tipos resumen los tipos de C#:

Tabla de tipos integrados


La siguiente tabla muestra las palabras clave para los tipos integrados de C#, las cuales son alias de tipos predefinidos en el espacio de nombres System.

Tipo de C#

Tipo de .NET Framework

bool byte sbyte char decimal double float int uint long ulong object short ushort string Comentarios

System.Boolean System.Byte System.SByte System.Char System.Decimal System.Double System.Single System.Int32 System.UInt32 System.Int64 System.UInt64 System.Object System.Int16 System.UInt16 System.String

Todos los tipos de la tabla, excepto object y string, se conocen como tipos simples. Las palabras clave de tipos de C# y sus alias son intercambiables. Por ejemplo, se puede declarar una variable entera de cualquiera de estas dos formas:

int x = 123; System.Int32 x = 123;


Para mostrar el tipo real de cualquier tipo de C#, utilice el mtodo del sistema GetType(). Por ejemplo, la siguiente instruccin muestra el alias de sistema que representa el tipo de

myVariable: Console.WriteLine(myVariable.GetType());
Tambin se puede utilizar el operador typeof.

MCT: Luis Dueas

Pag 21 de 148

.NET 2 C# .NET

Tabla de tipos integrales


La siguiente tabla muestra los tamaos e intervalos de los tipos integrales, que constituyen un subconjunto de los tipos simples.

Tipo

Intervalo

Tamao

sbyte byte char short ushort int uint long ulong

-128 a 127 0 a 255 U+0000 a U+ffff -32.768 a 32.767 0 a 65.535 -2.147.483.648 a 2.147.483.647 0 a 4.294.967.295 -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807 0 a 18.446.744.073.709.551.615

Entero de 8 bits con signo Entero de 8 bits sin signo Carcter Unicode de 16 bits Entero de 16 bits con signo Entero de 16 bits sin signo Entero de 32 bits con signo Entero de 32 bits sin signo Entero de 64 bits con signo Entero de 64 bits sin signo

Si el valor representado por un literal entero supera el intervalo de valores del tipo ulong, se producir un error de compilacin.

Tabla de tipos de punto flotante


La siguiente tabla muestra la precisin y el intervalo aproximado para los tipos de punto flotante.

Tipo

Intervalo aproximado 1,5e45 a 3,4e38 5,0e324 a 1,7e308

Precisin

float double

7 dgitos 15-16 dgitos

Tabla de valores predeterminados


La siguiente tabla muestra los valores predeterminados de los tipos de valor devueltos por los constructores predeterminados. Los constructores predeterminados se invocan mediante el operador new, de la manera siguiente:

int myInt = new int();


La instruccin anterior tiene el mismo efecto que la instruccin siguiente:

int myInt = 0;
Recuerde que el uso de variables no inicializadas no est permitido en C#.

MCT: Luis Dueas

Pag 22 de 148

.NET 2 C# .NET

Tipo de valor

Valor predeterminado

bool byte char decimal double enum float int long sbyte short struct

false 0 '\0' 0,0M 0,0D El valor producido por la expresin (E)0, donde E es el identificador de la enumeracin. 0,0F 0 0L 0 0 El valor obtenido al asignar los valores predeterminados a los campos de tipo de valor y el valor null a los campos de tipo de referencia. 0 0 0

uint ulong ushort

Tabla de tipos de valores


En la tabla siguiente, se enumeran los tipos de valor de C# por categoras.

Tipo de valor

Categora

bool byte char decimal double enum float int long

Booleano Sin signo, numrica, integral Sin signo, numrica, integral Numrica, decimal Numrica, de punto flotante Enumeracin Numrica, de punto flotante Con signo, numrica, integral Con signo, numrica, integral

MCT: Luis Dueas

Pag 23 de 148

.NET 2 C# .NET
sbyte short struct uint ulong ushort Con signo, numrica, integral Con signo, numrica, integral Estructura definida por el usuario Sin signo, numrica, integral Sin signo, numrica, integral Sin signo, numrica, integral

Tabla de conversiones numricas implcitas


La tabla siguiente muestra las conversiones numricas implcitas predefinidas. Las conversiones implcitas se pueden dar en muchas ocasiones, incluidas la invocacin a mtodos y las instrucciones de asignacin.

De

sbyte byte short ushort int uint long char float ulong

short, int, long, float, double o decimal short, ushort, int, uint, long, ulong, float, double o decimal int, long, float, double o decimal int, uint, long, ulong, float, double o decimal long, float, double o decimal long, ulong, float, double o decimal float, double o decimal ushort, int, uint, long, ulong, float, double o decimal double float, double o decimal Comentarios

Las conversiones de int, uint o long a float y de long a double pueden causar una prdida de precisin, pero no una prdida de magnitud. No existen conversiones implcitas al tipo char. No hay ninguna conversin implcita entre los tipos de punto flotante y el tipo decimal. Una expresin constante de tipo int se puede convertir a sbyte, byte, short, ushort, uint o ulong, siempre que el valor de la expresin constante quede dentro del intervalo del tipo de destino.

MCT: Luis Dueas

Pag 24 de 148

.NET 2 C# .NET

Tabla de conversiones numricas explcitas


Las conversiones numricas explcitas se utilizan para convertir cualquier tipo numrico a cualquier otro tipo numrico, para el que no existe conversin implcita, mediante una expresin que utilice el operador de conversin explcita. La siguiente tabla muestra estas conversiones.

De

Para

sbyte byte short ushort int uint long ulong char float double decimal

byte, ushort, uint, ulong o char Sbyte o char sbyte, byte, ushort, uint, ulong o char sbyte, byte, short o char sbyte, byte, short, ushort, uint, ulong o char sbyte, byte, short, ushort, int o char sbyte, byte, short, ushort, int, uint, ulong o char sbyte, byte, short, ushort, int, uint, long o char sbyte, byte o short sbyte, byte, short, ushort, int, uint, long, ulong, char o decimal sbyte, byte, short, ushort, int, uint, long, ulong, char, float o decimal sbyte, byte, short, ushort, int, uint, long, ulong, char, float o double Comentarios

Las conversiones numricas explcitas pueden producir prdida de precisin o provocar excepciones. Cuando se convierte un valor decimal en un tipo integral, este valor se redondea hacia cero al valor entero ms prximo. Si el valor entero resultante queda fuera del intervalo del tipo de destino, se produce una excepcin OverflowException.

Cuando se convierte un valor double o float en un tipo integral, el valor se trunca. Si el valor entero resultante queda fuera del intervalo del valor de destino, el resultado depende del contexto de comprobacin de desbordamiento. En un contexto comprobado, se produce una excepcin OverflowException, mientras que en un contexto no comprobado, el resultado es un valor no especificado del tipo de destino.

Cuando se convierte double en float, el valor double se redondea al valor float ms prximo. Si el valor de tipo double es demasiado pequeo o demasiado grande para ajustarse al tipo de destino, el resultado ser cero o infinito.

Cuando se convierte float o double en decimal, el valor de origen se convierte en una representacin decimal y se redondea al nmero ms prximo despus de la vigsimo octava posicin decimal si es necesario. Segn el valor de origen, se puede producir uno de los siguientes resultados:

Si el valor de origen es demasiado pequeo para representarlo como decimal, el resultado se convierte en cero.

MCT: Luis Dueas

Pag 25 de 148

.NET 2 C# .NET
o
Si el valor de origen es NaN (no es un nmero), infinito o demasiado grande para ser representado como decimal, se produce una excepcin OverflowException. Cuando se convierte decimal en float o double, el valor decimal se redondea al valor double o float ms prximo.

Aplicar formato a la tabla de resultados numricos


Se puede dar formato a los resultados numricos mediante el mtodo String.Format o a travs del mtodo Console.Write, el cual llama a String.Format. El formato se determina mediante las cadenas de formato. La tabla siguiente contiene las cadenas de formato estndar admitidas. La cadena de formato tiene la forma siguiente: Axx,, donde A es el especificador de formato y xx es el especificador de precisin. El especificador de formato controla el tipo de formato aplicado al valor numrico, mientras que el especificador de precisin controla el nmero de dgitos significativos o posiciones decimales del resultado.

Carcter

Descripcin

Ejemplos

Resultados

Coc

Moneda

Console.Write("{0:C}", 2,5); Console.Write("{0:C}", -2,5); Console.Write("{0:D5}", 25); Console.Write("{0:E}", 250000); Console.Write("{0:F2}", 25); Console.Write("{0:F0}", 25); Console.Write("{0:G}", 2,5); Console.Write("{0:N}", 2500000); Console.Write("{0:X}", 250); Console.Write("{0:X}", 0xffff);

$2.50 ($2.50) 00025 2,500000E+005 25.00 25 2.5 2.500.000,00 FA FFFF

Dod Eoe Fof

Decimal Cientfico Punto fijo

Gog Non Xox

General Nmero Hexadecimal

MCT: Luis Dueas

Pag 26 de 148

.NET 2 C# .NET

Modificadores
Los modificadores se utilizan para modificar declaraciones de tipos y miembros de tipos. Esta seccin presenta los siguientes modificadores de C#:

Modificador

Finalidad

Modificadores de acceso public private internal protected abstract const event extern

Especificar la accesibilidad declarada de tipos y miembros de tipos.

Indica que una clase est definida slo como clase base de otras clases. Especifica que el valor del campo o de la variable local no se pueden modificar. Declara un evento. Indica que el mtodo est implementado externamente. new Oculta un miembro heredado de un miembro de clase base. Proporciona una nueva implementacin de un miembro virtual heredado de una clase base. Define clases y estructuras parciales a lo largo del mismo ensamblado. Declara un campo al cual slo se pueden asignar valores como parte de la declaracin o en un constructor de la misma clase. Especifica que una clase no se puede heredar. Declara un miembro que pertenece al propio tipo en vez de a un objeto especfico. Declara un contexto no seguro. Declara un mtodo o un descriptor de acceso cuya implementacin se puede cambiar mediante un miembro de reemplazo perteneciente a una clase derivada. Indica que un campo puede ser modificado en el programa por el sistema operativo, el hardware o un subproceso en ejecucin de forma simultnea.

override partial readonly

sealed static unsafe virtual

volatile

Modificadores de acceso
Los modificadores de acceso son palabras clave que especifican la accesibilidad declarada de un miembro o un tipo. Esta seccin presenta los cuatro modificadores de acceso:

public protected internal private

Mediante los modificadores de acceso se pueden especificar los siguientes cinco niveles de accesibilidad:

MCT: Luis Dueas

Pag 27 de 148

.NET 2 C# .NET
public: acceso no restringido. protected: acceso limitado a la clase contenedora o a los tipos derivados de esta clase. Internal: acceso limitado al ensamblado actual. protected internal: acceso limitado al ensamblado actual o los tipos derivados de la clase contenedora. private: acceso limitado al tipo contenedor. Esta seccin tambin presenta los siguientes temas:

Niveles de accesibilidad: utilizar los cuatro modificadores de acceso para declarar cinco niveles de accesibilidad. Dominio de accesibilidad: especifica dnde se puede hacer referencia a un miembro en las secciones de programa. Restricciones en el uso de los niveles de accesibilidad: resumen de las restricciones en el uso de los niveles de accesibilidad declarados.

Niveles de accesibilidad
Utilice los modificadores de acceso public, protected, internal o private para especificar una de las siguientes accesibilidades declaradas para miembros.

Accesibilidad declarada

Significado

public protected internal protected internal private

Acceso no restringido. Acceso limitado a la clase contenedora o a los tipos derivados de esta clase. Acceso limitado al proyecto actual. Acceso limitado al proyecto actual o a los tipos derivados de la clase contenedora. Acceso limitado al tipo contenedor.

Slo se permite un modificador de acceso para un miembro o tipo, excepto cuando se utiliza la combinacin protected internal. Los modificadores de acceso no se pueden utilizar en espacios de nombres. Los espacios de nombres no presentan restricciones de acceso. Segn el contexto en el que se produce una declaracin de miembro, slo se permite declarar ciertos tipos de acceso. Si no se especifica ningn modificador de acceso en una declaracin de miembro, se utiliza el tipo de acceso predeterminado. Los tipos de nivel superior, que no estn anidados en otros tipos, slo pueden tener accesibilidad internal o public. La accesibilidad predeterminada para estos tipos es internal. Los tipos anidados, que son miembros de otros tipos, pueden tener un tipo de acceso declarado como el que se indica en la siguiente tabla.

MCT: Luis Dueas

Pag 28 de 148

.NET 2 C# .NET

Miembros de

Accesibilidad predeterminada

Accesibilidades declaradas permitidas

enum class

public private

Ninguna public protected internal private protected internal Ninguna public internal private

interface struct

public private

La accesibilidad de un tipo anidado depende de su dominio de accesibilidad, el cual se determina mediante la accesibilidad declarada para el miembro y el dominio de accesibilidad del tipo inmediato que lo contiene. Sin embargo, el dominio de accesibilidad de un tipo anidado no puede exceder al del tipo contenedor.

Dominio de accesibilidad
El dominio de accesibilidad de un miembro especifica en qu secciones del programa se puede hacer referencia a un miembro. Si el miembro est anidado dentro de otro tipo, su dominio de accesibilidad viene determinado por el nivel de accesibilidad del miembro y por el dominio de accesibilidad del tipo contenedor inmediato. El dominio de accesibilidad de un tipo de nivel superior es, al menos, el texto del programa del proyecto en el que aparece declarado. Es decir, todos los archivos de cdigo fuente del proyecto. El dominio de accesibilidad de un tipo anidado es, al menos, el texto del programa en el que el tipo aparece declarado. Es decir, el cuerpo del tipo, incluidos los tipos anidados. El dominio de accesibilidad de un tipo anidado no puede superar al del tipo contenedor. Estos conceptos se muestran en el siguiente ejemplo. Ejemplo Este ejemplo contiene un tipo de nivel superior, T1, y dos clases anidadas, M1 y M2. Las clases contienen campos con diferentes accesibilidades declaradas. En el mtodo Main, a cada instruccin le sigue un comentario que indica el dominio de accesibilidad de cada miembro. Observe que las instrucciones que intentan hacer referencia a los miembros inaccesibles estn desactivadas mediante signos de comentario. Si desea ver los errores generados por el compilador cuando se intenta hacer referencia a un miembro inaccesible, quite los comentarios de uno en uno.

// cs_Accessibility_Domain.cs using System; namespace AccessibilityDomainNamespace { public class T1 { public static int publicInt;

MCT: Luis Dueas

Pag 29 de 148

.NET 2 C# .NET
internal static int internalInt; private static int privateInt = 0; // CS0414 public class M1 { public static int publicInt; internal static int internalInt; private static int privateInt = 0; // CS0414 } private class M2 { public static int publicInt = 0; internal static int internalInt = 0; private static int privateInt = 0; // CS0414 } } class MainClass { static void Main() { // Access is unlimited: T1.publicInt = 1; // Accessible only in current assembly: T1.internalInt = 2; // Error: inaccessible outside T1: // T1.myPrivateInt = 3; // Access is unlimited: T1.M1.publicInt = 1; // Accessible only in current assembly: T1.M1.internalInt = 2; // Error: inaccessible outside M1: // T1.M1.myPrivateInt = 3; // Error: inaccessible outside T1: // T1.M2.myPublicInt = 1; // Error: inaccessible outside T1: // T1.M2.myInternalInt = 2; // Error: inaccessible outside M2: // T1.M2.myPrivateInt = 3; } } }

MCT: Luis Dueas

Pag 30 de 148

.NET 2 C# .NET

Restricciones en el uso de los niveles de accesibilidad


Cuando se declara un tipo, es esencial determinar si ese tipo tiene que ser al menos tan accesible como otro miembro o tipo. Por ejemplo, la clase base directa debe ser al menos tan accesible como la clase derivada. Las siguientes declaraciones producirn un error del compilador, ya que la clase base BaseClass es menos accesible que MyClass:

class BaseClass { ... } public class MyClass: BaseClass { ... } // Error


La siguiente tabla resume las restricciones de uso de los niveles de accesibilidad declarados.

Contexto

Comentarios

Clases Interfaces

La clase base directa de un tipo de clase debe ser al menos tan accesible como el propio tipo de clase. Las interfaces base explcitas de un tipo de interfaz deben ser al menos tan accesibles como el propio tipo de interfaz. El tipo de valor devuelto y los tipos de los parmetros de un tipo delegado deben ser al menos tan accesibles como el propio tipo delegado. El tipo de una constante debe ser al menos tan accesible como la propia constante. El tipo de un campo debe ser al menos tan accesible como el propio campo. El tipo de valor devuelto y los tipos de parmetros de un mtodo deben ser al menos tan accesibles como el propio mtodo. El tipo de una propiedad debe ser al menos tan accesible como la misma propiedad. El tipo de un evento debe ser al menos tan accesible como el propio evento. El tipo y los tipos de parmetros de un indizador deben ser al menos tan accesibles como el propio indizador. El tipo de valor devuelto y los tipos de parmetros de un operador deben ser al menos tan accesibles como el propio operador. Los tipos de parmetros de un constructor deben ser al menos tan accesibles como el propio constructor.

Delegados

Constantes Campos Mtodos

Propiedades Eventos Indizadores

Operadores

Constructores

Ejemplo El siguiente ejemplo contiene declaraciones errneas de diferentes tipos. El comentario que sigue a cada declaracin indica el error esperado del compilador.

// Restrictions_on_Using_Accessibility_Levels.cs // CS0052 expected as well as CS0053, CS0056, and CS0057 // To make the program work, change access level of both class B // and MyPrivateMethod() to public. using System; // A delegate:

MCT: Luis Dueas

Pag 31 de 148

.NET 2 C# .NET
delegate int MyDelegate(); class B { // A private method: static int MyPrivateMethod() { return 0; } } public class A { // Error: The type B is less accessible than the field A.myField. public B myField = new B(); // Error: The type B is less accessible // than the constant A.myConst. public readonly B myConst = new B(); public B MyMethod() { // Error: The type B is less accessible // than the method A.MyMethod. return new B(); } // Error: The type B is less accessible than the property A.MyProp public B MyProp { set { } } MyDelegate d = new MyDelegate(B.MyPrivateMethod); // Even when B is declared public, you still get the error: // "The parameter B.MyPrivateMethod is not accessible due to // protection level." public static B operator +(A m1, B m2) { // Error: The type B is less accessible // than the operator A.operator +(A,B) return new B(); } static void Main() { Console.Write("Compiled successfully"); } }

MCT: Luis Dueas

Pag 32 de 148

.NET 2 C# .NET

internal
La palabra clave internal es un modificador de acceso para tipos y miembros de tipos. Los tipos o miembros internos slo son accesibles dentro de los archivos del mismo ensamblado, como en este ejemplo:

public class BaseClass { // Only accessible within the same assembly internal static int x = 0; }
Encontrar una comparacin de internal con los otros modificadores de acceso en Niveles de accesibilidad y Modificadores de acceso (Gua de programacin de C#). Un uso habitual del acceso de tipo interno se da en el desarrollo basado en componentes, ya que permite a un grupo de componentes cooperar de manera privada sin estar expuesto al resto del cdigo de la aplicacin. Por ejemplo, una estructura para crear interfaces grficas de usuario podra proporcionar clases Control y Form que cooperan mediante miembros con acceso de tipo internal. Como estos miembros son internos, no estn expuestos al cdigo que utiliza la estructura. Si se hace referencia a un tipo o miembro con acceso interno fuera del ensamblado en el que se defini, produce un error.

Nota

El mtodo internal virtual puede reemplazarse en algunos lenguajes, como en el Lenguaje intermedio de Microsoft (MSIL) textual mediante Ilasm.exe, aunque no se pueda reemplazar utilizando C#. Ejemplo Este ejemplo contiene dos archivos, Assembly1.cs y Assembly2.cs. El primer archivo contiene una clase base interna, BaseClass. En el segundo archivo, un intento de crear instancias BaseClass generar un error.

// Assembly1.cs // compile with: /target:library internal class BaseClass { public static int intM = 0; } // Assembly1_a.cs // compile with: /reference:Assembly1.dll class TestAccess { static void Main() { BaseClass myBase = new BaseClass(); // CS0122 } }

MCT: Luis Dueas

Pag 33 de 148

.NET 2 C# .NET
En este ejemplo, utilice los mismos archivos que utiliz en el primer ejemplo y cambie el nivel de accesibilidad de BaseClass a public. Adems cambie el nivel de accesibilidad del miembro IntM a internal. En este caso, puede crear instancias de la clase, pero no puede tener acceso al miembro interno.

// Assembly2.cs // compile with: /target:library public class BaseClass { internal static int intM = 0; } // Assembly2_a.cs // compile with: /reference:Assembly1.dll public class TestAccess { static void Main() { BaseClass myBase = new BaseClass(); // Ok. BaseClass.intM = 444; // CS0117 } }

private
La palabra clave private es un modificador de acceso de miembros. El acceso de tipo private corresponde al nivel de acceso ms restrictivo. Los miembros privados slo son accesibles dentro del cuerpo de la clase o estructura en la que se declaran, como en el siguiente ejemplo.

class Employee { private int i; double d; // private access by default }


Los tipos anidados del mismo cuerpo tambin pueden tener acceso a esos miembros privados. Hacer referencia a un miembro privado fuera de la clase o estructura en la que se declara produce un error de compilacin. Ejemplo En este ejemplo, la clase Employee contiene dos miembros de datos privados, name y salary. Como miembros privados, slo pueden tener acceso a ellos los mtodos miembro; por tanto, hay que agregar los mtodos pblicos denominados GetName y Salary para permitir el acceso controlado a los miembros privados. Se tiene acceso al miembro name a travs del mtodo pblico y se tiene acceso al miembro salary a travs de una propiedad pblica de slo lectura.

// private_keyword.cs using System; class Employee { private string name = "FirstName, LastName"; private double salary = 100.0; public string GetName()

MCT: Luis Dueas

Pag 34 de 148

.NET 2 C# .NET
{ return name; } public double Salary { get { return salary; } } } class MainClass { static void Main() { Employee e = new Employee(); // The data members are inaccessible (private), so // then can't be accessed like this: // string n = e.name; // double s = e.salary; // 'name' is indirectly accessed via method: string n = e.GetName(); // 'salary' is indirectly accessed via property double s = e.Salary; } }

protected
La palabra clave protected es un modificador de acceso a miembros. Un miembro protegido es accesible dentro de su clase y por clases derivadas. Encontrar una comparacin de protected con los otros modificadores de acceso en Niveles de accesibilidad. Un miembro protegido de una clase base es accesible en una clase derivada slo si el acceso se realiza a travs del tipo de la clase derivada. Por ejemplo, considere el siguiente segmento de cdigo:

// protected_keyword.cs using System; class A { protected int x = 123; } class B : A { static void Main() { A a = new A();

MCT: Luis Dueas

Pag 35 de 148

.NET 2 C# .NET
B b = new B(); // Error CS1540, because x can only be accessed by // classes derived from A. // a.x = 10; // OK, because this class derives from A. b.x = 10; } } La instruccin a.x =10 genera un error, ya que A no se deriva de B.
Los miembros de una estructura no se pueden proteger, ya que la estructura no se puede heredar. Ejemplo En este ejemplo, la clase DerivedPoint se deriva de Point; por lo tanto, puede obtener acceso a los miembros protegidos de la clase base directamente desde la clase derivada.

// protected_keyword_2.cs using System; class Point { protected int x; protected int y; } class DerivedPoint: Point { static void Main() { DerivedPoint dp = new DerivedPoint(); // Direct access to protected members: dp.x = 10; dp.y = 15; Console.WriteLine("x = {0}, y = {1}", dp.x, dp.y); } }
Resultados

x = 10, y = 15
Comentarios Si se cambian los niveles de acceso de x e y a private, el compilador producir los siguientes mensajes de error:

'Point.y' is inaccessible due to its protection level. 'Point.x' is inaccessible due to its protection level.

public
La palabra clave public es un modificador de acceso para tipos y miembros de tipos. El acceso de tipo public corresponde al nivel de acceso menos restrictivo. No existen restricciones para obtener acceso a los miembros pblicos, como en este ejemplo:

class SampleClass { public int x; // No access restrictions. }


Ejemplo En el siguiente ejemplo, se declaran dos clases, Point y MainClass. El acceso a los miembros pblicos x e y de Point se realiza directamente desde MainClass.

MCT: Luis Dueas

Pag 36 de 148

.NET 2 C# .NET
// protected_public.cs // Public access using System; class Point { public int x; public int y; } class MainClass { static void Main() { Point p = new Point(); // Direct access to public members: p.x = 10; p.y = 15; Console.WriteLine("x = {0}, y = {1}", p.x, p.y); } }
Resultado

x = 10, y = 15
Si se cambia el nivel de acceso de public a private o protected, se aparecer el siguiente mensaje de error:

'Point.y' is inaccessible due to its protection level.

abstract
El modificador abstract se puede utilizar con clases, mtodos, propiedades, indizadores y eventos. Use el modificador abstract en una declaracin de clase para indicar que la clase slo se puede utilizar como clase base de otras clases. Los miembros que estn marcados como abstractos o que se incluyen en una clase abstracta, deben ser implementados por clases derivadas de la clase abstracta. En este ejemplo, la clase Square debe proporcionar una implementacin de Area porque deriva de ShapesClass:

abstract class ShapesClass { abstract public int Area(); } class Square : ShapesClass { int x, y; // Not providing an Area method results // in a compile-time error. public override int Area() { return x * y; } }
Comentarios

MCT: Luis Dueas

Pag 37 de 148

.NET 2 C# .NET
Las clases de tipo abstract presentan las siguientes caractersticas:

No se pueden crear instancias de una clase abstracta. Una clase abstracta puede contener descriptores de acceso y mtodos abstractos. No es posible modificar una clase abstracta con el modificador sealed (Referencia de C#), lo cual significa que la clase no se puede heredar. Una clase no abstracta derivada de una clase abstracta debe incluir implementaciones reales de todos los descriptores de acceso y mtodos abstractos heredados.

Utilice el modificador abstract en una declaracin de mtodo o propiedad para indicar que el mtodo o la propiedad no contienen implementacin. Los mtodos abstractos presentan las siguientes caractersticas:

Un mtodo abstracto es, implcitamente, un mtodo virtual. Las declaraciones de mtodos abstractos slo se permiten en clases abstractas. Debido a que una declaracin de mtodo abstracto no proporciona una implementacin, no existe cuerpo del mtodo; la declaracin de mtodo finaliza simplemente con un punto y coma y sin llaves ({ }) despus de la firma. Por ejemplo:

public abstract void MyMethod();


La implementacin la proporciona un mtodo de reemplazo, que es miembro de una clase no abstracta. Utilizar los modificadores static o virtual en una declaracin de mtodo abstracto produce un error. Las propiedades abstractas funcionan como los mtodos abstractos, salvo las diferencias en la sintaxis de las declaraciones y llamadas.

Es incorrecto utilizar el modificador abstract para una propiedad esttica. Una propiedad abstracta heredada se puede reemplazar en una clase derivada si se incluye una declaracin de propiedad que utilice el modificador override.

Una clase abstracta debe proporcionar implementaciones para todos los miembros de la interfaz. Una clase abstracta que implementa una interfaz podra asignar los mtodos de la interfaz a mtodos abstractos. Por ejemplo:

interface I { void M(); } abstract class C: I { public abstract void M(); }


Ejemplo En este ejemplo, la clase DerivedClass se deriva de una clase abstracta BaseClass. La clase abstracta contiene un mtodo abstracto, AbstractMethod, y dos propiedades abstractas, X y Y.

// abstract_keyword.cs // Abstract Classes using System; abstract class BaseClass // Abstract class { protected int _x = 100; protected int _y = 150; public abstract void AbstractMethod();

MCT: Luis Dueas

Pag 38 de 148

.NET 2 C# .NET
// Abstract method public abstract int X { get; } public abstract int Y { get; } } class DerivedClass : BaseClass { public override void AbstractMethod() { _x++; _y++; } public override int X // overriding property { get { return _x + 10; } } public override int Y // overriding property { get { return _y + 10; } } static void Main() { DerivedClass o = new DerivedClass(); o.AbstractMethod(); Console.WriteLine("x = {0}, y = {1}", o.X, o.Y); } }
Resultados

x = 111, y = 161

const
La palabra clave const se utiliza para modificar una declaracin de un campo o una variable local. Especifica que el valor del campo o de la variable local es constante, o sea que no se puede modificar. Por ejemplo:

const int x = 0; public const double gravitationalConstant = 6.673e-11;

MCT: Luis Dueas

Pag 39 de 148

.NET 2 C# .NET
private const string productName = "Visual C#";
Comentarios El tipo de una declaracin de constantes especifica el tipo de los miembros que se incluyen en la declaracin. Una expresin constante debe dar un valor del tipo destino o de un tipo que se pueda convertir implcitamente en el tipo destino. Una expresin constante es una expresin que se puede evaluar completamente en tiempo de compilacin. Por consiguiente, los nicos valores posibles para constantes de tipos de referencia son string, y null. La declaracin de constante puede declarar varias constantes, por ejemplo:

public const double x = 1.0, y = 2.0, z = 3.0;


El modificador static no se puede utilizar en una declaracin de constante. Una constante puede participar en una expresin constante, por ejemplo:

public const int c1 = 5; public const int c2 = c1 + 100;


Nota

La palabra clave readonly es diferente de la palabra clave const. Un campo const slo puede inicializarse en la declaracin del campo. Un campo readonly puede inicializarse en la declaracin o en un constructor. Por lo tanto, los campos readonly pueden tener diferentes valores en funcin del constructor que se utilice. Adems, mientras que un campo const es una constante en tiempo de compilacin, el campo readonly puede utilizarse para constantes en tiempo de ejecucin, como muestra la lnea siguiente:

public static readonly uint l1 = (uint)DateTime.Now.Ticks;


Ejemplo

// const_keyword.cs using System; public class ConstTest { class SampleClass { public int x; public int y; public const int c1 = 5; public const int c2 = c1 + 5; public SampleClass(int p1, int p2) { x = p1; y = p2; } } static void Main() { SampleClass mC = new SampleClass(11, 22); Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); Console.WriteLine("c1 = {0}, c2 = {1}", SampleClass.c1, SampleClass.c2 ); } }

MCT: Luis Dueas

Pag 40 de 148

.NET 2 C# .NET
Resultados

x = 11, y = 22 c1 = 5, c2 = 10
Este ejemplo muestra el uso de constantes como variables locales.

// const_keyword_2.cs using System; public class MainClass { static void Main() { const int c = 707; Console.WriteLine("My local constant = {0}", c); } }
Resultados

My local constant = 707

event
La palabra clave event se utiliza para especificar un evento. Comentarios Los eventos se utilizan en las clases y estructuras para notificar a los objetos acciones que pueden afectar a su estado. Por ejemplo, los formularios Windows Forms tienen un evento System.Windows.Forms.Form.Activated que se puede utilizar para desencadenar cdigo cada vez que el formulario pasa a estado activo. Para agregar un evento a una clase es preciso utilizar la palabra clave event, proporcionar un tipo de delegado y un nombre para el evento. En este ejemplo, se define un delegado y, a continuacin, se asocia al evento SampleEvent.

public delegate void SampleEventDelegate(object sender, EventArgs e); public class SampleEventSource { public event SampleEventDelegate SampleEvent; }

extern
El modificador extern se utiliza para declarar un mtodo que se implementa externamente. Un uso comn del modificador extern es con el atributo DllImport cuando se utilizan servicios de interoperabilidad para llamar en cdigo no administrado; en este caso, el mtodo tambin debe declararse como static, tal como se muestra en el ejemplo siguiente:

[DllImport("avifil32.dll")] private static extern void AVIFileInit();


Nota

MCT: Luis Dueas

Pag 41 de 148

.NET 2 C# .NET
La palabra clave extern tambin puede definir un alias de ensamblado externo, lo que hace posible hacer referencia a diferentes versiones del mismo componente desde un nico ensamblado. Para obtener ms informacin, vea alias externo (Referencia de C#). Es incorrecto utilizar simultneamente los modificadores abstract (Referencia de C#) y extern para modificar el mismo miembro. El uso del modificador extern significa que el mtodo se implementa fuera del cdigo de C#, mientras que el uso del modificador abstract significa que la clase no incluye la implementacin del mtodo.

Nota

El uso de la palabra clave extern es ms limitado que en C++. Para compararla con la palabra clave de C++, vea Using extern to Specify Linkage en la Referencia del lenguaje C++. Ejemplo En este ejemplo, el programa recibe una cadena del usuario y la muestra dentro de un cuadro de mensaje. El programa utiliza el mtodo MessageBox importado de la biblioteca User32.dll.

using System; using System.Runtime.InteropServices; class MainClass { [DllImport("User32.dll")] public static extern int MessageBox(int h, string m, string c, int type); static int Main() { string myString; Console.Write("Enter your message: "); myString = Console.ReadLine(); return MessageBox(0, myString, "My Message Box", 0); } }
En este ejemplo se crea un archivo DLL desde un programa de C invocado desde el programa de C# del siguiente ejemplo.

// cmdll.c // compile with: /LD int __declspec(dllexport) SampleMethod(int i) { return i*10; } Este ejemplo utiliza dos archivos, CM.cs y Cmdll.c, para demostrar el uso de extern. El archivo
C es un archivo DLL externo creado en el ejemplo 2 que se invoca desde el programa escrito en C#.

// cm.cs using System; using System.Runtime.InteropServices; public class MainClass { [DllImport("Cmdll.dll")] public static extern int SampleMethod(int x);

MCT: Luis Dueas

Pag 42 de 148

.NET 2 C# .NET
static void Main() { Console.WriteLine("SampleMethod() returns {0}.", SampleMethod(5)); } }
Resultados

SampleMethod() returns 50.

override
El modificador override es necesario para ampliar o modificar la implementacin abstracta o virtual de un mtodo, propiedad, indizador o evento heredado. En este ejemplo, la clase Square debe proporcionar una implementacin de reemplazo de Area porque sta se hereda de la clase abstracta ShapesClass:

abstract class ShapesClass { abstract public int Area(); } class Square : ShapesClass { int x, y; // Because ShapesClass.Area is abstract, failing to override // the Area method would result in a compilation error. public override int Area() { return x * y; } }
Comentarios El mtodo override proporciona una nueva implementacin de un miembro heredado de una clase base. El mtodo reemplazado por una declaracin override se conoce como mtodo base reemplazado. El mtodo base reemplazado debe tener la misma firma que el mtodo override. No se puede reemplazar un mtodo esttico o no virtual. El mtodo base reemplazado debe ser virtual, abstract u override. Una declaracin override no puede cambiar la accesibilidad del mtodo virtual. El mtodo override y el mtodo virtual deben tener el mismo modificador de nivel de acceso. No se pueden utilizar los modificadores new, static, virtual o abstract para modificar un mtodo override. Una declaracin de propiedad de reemplazo debe especificar el mismo modificador de acceso, tipo y nombre que la propiedad heredada, y la propiedad reemplazada debe ser virtual, abstract u override. Ejemplo

MCT: Luis Dueas

Pag 43 de 148

.NET 2 C# .NET
Este ejemplo define una clase base denominada Employee y una clase derivada denominada

SalesEmployee. La clase SalesEmployee incluye una propiedad adicional, salesbonus, y reemplaza al mtodo CalculatePay para tenerlo en cuenta. using System; class TestOverride { public class Employee { public string name; // Basepay is defined as protected, so that it may be // accessed only by this class and derrived classes. protected decimal basepay; // Constructor to set the name and basepay values. public Employee(string name, decimal basepay) { this.name = name; this.basepay = basepay; } // Declared virtual so it can be overridden. public virtual decimal CalculatePay() { return basepay; } } // Derive a new class from Employee. public class SalesEmployee : Employee { // New field that will affect the base pay. private decimal salesbonus; // The constructor calls the base-class version, and // initializes the salesbonus field. public SalesEmployee(string name, decimal basepay, decimal salesbonus) : base(name, basepay) { this.salesbonus = salesbonus; } // Override the CalculatePay method // to take bonus into account. public override decimal CalculatePay() { return basepay + salesbonus; } } static void Main() { // Create some new employees. SalesEmployee employee1 = new SalesEmployee("Alice", 1000, 500); Employee employee2 = new Employee("Bob", 1200); Console.WriteLine("Employee " + employee1.name + " earned: " + employee1.CalculatePay());

MCT: Luis Dueas

Pag 44 de 148

.NET 2 C# .NET
Console.WriteLine("Employee " + employee2.name + " earned: " + employee2.CalculatePay()); } }
Resultados

Employee Alice earned: 1500 Employee Bob earned: 1200

readonly
La palabra clave readonly corresponde a un modificador que se puede utilizar en campos. Cuando una declaracin de campo incluye un modificador readonly, las asignaciones a los campos que aparecen en la declaracin slo pueden tener lugar en la propia declaracin o en un constructor de la misma clase. En este ejemplo, el valor del campo year no se puede cambiar en el mtodo

ChangeYear, aunque se asigne un valor en el constructor de clase: class Age { readonly int _year; Age(int year) { _year = year; } void ChangeYear() { _year = 1967; // Will not compile. } }
Comentarios Slo se puede asignar un valor a un campo readonly en los siguientes contextos:

Cuando la variable se inicializa en la declaracin, por ejemplo:

public readonly int y = 5;


Para un campo de instancia, en los constructores de instancia de la clase que contiene la declaracin de campo; para un campo esttico, en el constructor esttico de la clase que contiene la declaracin de campo. stos son tambin los nicos contextos en los que es vlido pasar un campo readonly como parmetro out o ref.

Nota

La palabra clave readonly es diferente de la palabra clave const. Un campo const slo puede inicializarse en la declaracin del campo. Un campo readonly puede inicializarse en la declaracin o en un constructor. Por lo tanto, los campos readonly pueden tener diferentes valores en funcin del constructor que se utilice. Adems, mientras que un campo const es una constante en tiempo de compilacin, el campo readonly puede utilizarse para constantes en tiempo de ejecucin, como muestra el siguiente ejemplo:

Nota

public static readonly uint l1 = (uint)DateTime.Now.Ticks;


Ejemplo

// cs_readonly_keyword.cs

MCT: Luis Dueas

Pag 45 de 148

.NET 2 C# .NET
// Readonly fields using System; public class ReadOnlyTest { class SampleClass { public int x; // Initialize a readonly field public readonly int y = 25; public readonly int z; public SampleClass() { // Initialize a readonly instance field z = 24; } public SampleClass(int p1, int p2, int p3) { x = p1; y = p2; z = p3; } } static void Main() { SampleClass p1 = new SampleClass(11, 21, 32); // OK Console.WriteLine("p1: x={0}, y={1}, z={2}", p1.x, p1.y, p1.z); SampleClass p2 = new SampleClass(); p2.x = 55; // OK Console.WriteLine("p2: x={0}, y={1}, z={2}", p2.x, p2.y, p2.z); } }
Resultados

p1: x=11, y=21, z=32 p2: x=55, y=25, z=24

sealed
El modificador sealed se puede aplicar a clases, mtodos de instancia y propiedades. Una clase sealed no se puede heredar. Un mtodo sellado reemplaza un mtodo en una clase base, pero no se puede reemplazar tambin en una clase derivada. Cuando se aplica a un mtodo o propiedad, el modificador sealed siempre se debe utilizar con Override. Utilice el modificador sealed en una declaracin de clase para evitar que la clase se herede, como en este ejemplo:

sealed class SealedClass { public int x; public int y; }


Es un error utilizar una clase sellada como una clase base o utilizar el modificador abstract con una clase sellada. Las estructuras son tipos sealed implcitamente; por consiguiente, no se pueden heredar.

MCT: Luis Dueas

Pag 46 de 148

.NET 2 C# .NET
Ejemplo

// cs_sealed_keyword.cs using System; sealed class SealedClass { public int x; public int y; } class MainClass { static void Main() { SealedClass sc = new SealedClass(); sc.x = 110; sc.y = 150; Console.WriteLine("x = {0}, y = {1}", sc.x, sc.y); } }
Resultados

x = 110, y = 150
En el ejemplo anterior, si intenta heredar de la clase sealed mediante una instruccin como la siguiente:

class MyDerivedC: MyClass {} // Error


obtendr el siguiente mensaje de error:

'MyDerivedC' cannot inherit from sealed class 'MyClass'.

static
Utilice el modificador static para declarar un miembro esttico, que pertenece al propio tipo en vez de a un objeto especfico. El modificador static puede utilizarse con clases, campos, mtodos, propiedades operadores y eventos, pero no puede utilizarse con indizadores, destructores o tipos que no sean clases. Por ejemplo, la siguiente clase se declara como static y solo contiene mtodos static:

static class CompanyEmployee { public static string GetCompanyName(string name) { ... } public static string GetCompanyAddress(string address) { ... } }
Comentarios

Una declaracin de constante o tipo constituye, implcitamente, un miembro esttico.

MCT: Luis Dueas

Pag 47 de 148

.NET 2 C# .NET

No se puede hacer referencia a un miembro esttico por medio de una instancia. En vez de ello, se debe hacer referencia por medio del nombre de tipo. Por ejemplo, considere la siguiente clase:

public class MyBaseC { public struct MyStruct { public static int x = 100; } }
Para referirse al miembro esttico x, use el nombre completo (a menos que sea accesible desde el mismo mbito):

MyBaseC.MyStruct.x
Mientras que una instancia de una clase contiene una copia independiente de todos los campos de instancia de la clase, slo existe una copia de cada campo esttico. No es posible utilizar this para hacer referencia a descriptores de acceso de propiedades o mtodos static. Si la palabra clave static se aplica a una clase, todos los miembros de la clase deben ser estticos. Las clases, incluidas las clases estticas, pueden tener constructores estticos. Se llama a los constructores estticos en algn momento comprendido entre el inicio del programa y la creacin de instancias de la clase.

Nota

El uso de la palabra clave static es ms limitado que en C++. Para comparar con la palabra clave de C++, vea static. Para comprender el uso de miembros estticos, considere una clase que representa al empleado de una compaa. Suponga que la clase contiene un mtodo que cuenta empleados y un campo que almacena el nmero de empleados. Ni el mtodo ni el campo pertenecen a ninguna instancia de empleado. En vez de ello, pertenecen a la clase compaa. Por tanto, se deberan declarar como miembros estticos de la clase. Ejemplo Este ejemplo lee el nombre y el identificador de un nuevo empleado, incrementa en uno el contador de empleados y muestra la informacin del nuevo empleado, as como el nuevo nmero de empleados. Por motivos de simplicidad, el programa lee el nmero actual de empleados desde el teclado. En una aplicacin real, esta informacin se leera desde un archivo.

// cs_static_keyword.cs using System; public class Employee { public string id; public string name;

MCT: Luis Dueas

Pag 48 de 148

.NET 2 C# .NET
public Employee() { } public Employee(string name, string id) { this.name = name; this.id = id; } public static int employeeCounter; public static int AddEmployee() { return ++employeeCounter; } } class MainClass : Employee { static void Main() { Console.Write("Enter the employee's name: "); string name = Console.ReadLine(); Console.Write("Enter the employee's ID: "); string id = Console.ReadLine(); // Create and configure the employee object: Employee e = new Employee(name, id); Console.Write("Enter the current number of employees: "); string n = Console.ReadLine(); Employee.employeeCounter = Int32.Parse(n); Employee.AddEmployee(); // Display the new information: Console.WriteLine("Name: {0}", e.name); Console.WriteLine("ID: {0}", e.id); Console.WriteLine("New Number of Employees: {0}", Employee.employeeCounter); } }
Entrada

Tara Strahan AF643G 15


Resultados del ejemplo

Enter the employee's name: Tara Strahan Enter the employee's ID: AF643G Enter the current number of employees: 15 Name: Tara Strahan ID: AF643G New Number of Employees: 16
Este ejemplo muestra que aunque se puede inicializar un campo esttico con otro campo esttico an sin declarar, el resultado no estar definido hasta que no asigne explcitamente un valor al campo esttico.

// cs_static_keyword_2.cs using System; class Test { static int x = y; static int y = 5;

MCT: Luis Dueas

Pag 49 de 148

.NET 2 C# .NET
static void Main() { Console.WriteLine(Test.x); Console.WriteLine(Test.y); Test.x = 99; Console.WriteLine(Test.x); } }
Resultados

0 5 99

unsafe (Referencia de C#)


La palabra clave unsafe denota un contexto no seguro, que es necesario para cualquier operacin que involucre a punteros. Se puede utilizar el modificador unsafe en la declaracin de un tipo o un miembro. Toda la extensin textual del tipo o del miembro se considera, por lo tanto, como contexto no seguro. Por ejemplo, el siguiente mtodo se ha declarado con el modificador unsafe:

unsafe static void FastCopy(byte[] src, byte[] dst, int count) { // Unsafe context: can use pointers here. }
El mbito del contexto no seguro se extiende desde la lista de parmetros hasta el final del mtodo, de modo que tambin se pueden utilizar punteros en la lista de parmetros:

unsafe static void FastCopy ( byte* ps, byte* pd, int count ) { ... }
Tambin puede utilizar un bloque no seguro para habilitar el uso de cdigo no seguro dentro del mismo. Por ejemplo:

unsafe { // Unsafe context: can use pointers here. }


Para compilar cdigo no seguro, se debe especificar la opcin /unsafe del compilador. Common Language Runtime no puede comprobar el cdigo no seguro. Ejemplo

// cs_unsafe_keyword.cs // compile with: /unsafe using System; class UnsafeTest { // Unsafe method: takes pointer to int: unsafe static void SquarePtrParam(int* p) {

MCT: Luis Dueas

Pag 50 de 148

.NET 2 C# .NET
*p *= *p; } unsafe static void Main() { int i = 5; // Unsafe method: uses address-of operator (&): SquarePtrParam(&i); Console.WriteLine(i); } }
Resultados

25

virtual
La palabra clave virtual se utiliza para modificar un mtodo, propiedad, indizador o declaracin de evento y permite reemplazar a cualquiera de estos en una clase derivada. En el siguiente ejemplo, cualquier clase que hereda este mtodo puede reemplazarlo:

public virtual double Area() { return x * y; }


Comentarios Cuando se invoca un mtodo virtual, el tipo en tiempo de ejecucin del objeto se comprueba para ver si existe un miembro de reemplazo. Se realiza una llamada al miembro de reemplazo que est en la clase de mayor derivacin, el cual puede ser el miembro original, si no existe ninguna clase derivada que haya reemplazado el miembro. De forma predeterminada, los mtodos son no virtuales. No se puede reemplazar un mtodo no virtual. No puede utilizar el modificador virtual con los modificadores static, abstract y override. Las propiedades virtuales funcionan como los mtodos abstractos, salvo en lo que se refiere a las diferencias en la sintaxis de las declaraciones e invocaciones.

Es incorrecto utilizar el modificador virtual para una propiedad esttica. Una propiedad virtual heredada se puede reemplazar en una clase derivada si se incluye una declaracin de propiedad que use el modificador override. Ejemplo

En este ejemplo, la clase Dimensions contiene las dos coordenadas x, y, y el mtodo virtual

Area(). Las clases de las diferentes figuras, como Circle, Cylinder y Sphere, heredan la clase Dimensions, que permite calcular el rea de la superficie de cada figura. Cada clase derivada dispone de su propia implementacin de Area() (mtodo de reemplazo). El programa calcula y muestra el rea apropiada para cada implementacin del mtodo Area() segn el
objeto asociado al mtodo. Observe que todas las clases heredadas Circle, Sphere y Cylinder utilizan constructores que inicializan la clase base, por ejemplo:

public Cylinder(double r, double h): base(r, h) {}

MCT: Luis Dueas

Pag 51 de 148

.NET 2 C# .NET
Esto es anlogo a la lista de inicializaciones de C++.

// cs_virtual_keyword.cs using System; class TestClass { public class Dimensions { public const double PI = Math.PI; protected double x, y; public Dimensions() { } public Dimensions(double x, double y) { this.x = x; this.y = y; } public virtual double Area() { return x * y; } } public class Circle : Dimensions { public Circle(double r) : base(r, 0) { } public override double Area() { return PI * x * x; } } class Sphere : Dimensions { public Sphere(double r) : base(r, 0) { } public override double Area() { return 4 * PI * x * x; } } class Cylinder : Dimensions { public Cylinder(double r, double h) : base(r, h) { } public override double Area() {

MCT: Luis Dueas

Pag 52 de 148

.NET 2 C# .NET
return 2 * PI * x * x + 2 * PI * x * y; } } static void Main() { double r = 3.0, h = 5.0; Dimensions c = new Circle(r); Dimensions s = new Sphere(r); Dimensions l = new Cylinder(r, h); // Display results: Console.WriteLine("Area of Circle = {0:F2}", c.Area()); Console.WriteLine("Area of Sphere = {0:F2}", s.Area()); Console.WriteLine("Area of Cylinder = {0:F2}", l.Area()); } }
Resultados

Area of Circle = 28.27 Area of Sphere = 113.10 Area of Cylinder = 150.80

volatile
La palabra clave volatile indica que varios subprocesos que se ejecutan a la vez pueden modificar un campo. Los campos que se declaran como volatile no estn sujetos a optimizaciones del compilador que suponen el acceso por un subproceso nico. Esto garantiza que el valor ms actualizado est en todo momento presente en el campo. La palabra clave volatile se puede aplicar a estos tipos:

Tipos de referencia. Tipos de puntero (en un contexto no seguro). Tipos enteros como sbyte, byte, short, ushort, int, uint, char, float y bool. Tipos de enumeracin con un tipo base entero. Parmetros de tipo genricos que se sabe que son tipos de referencia. IntPtr y UIntPtr.

El tipo en cuestin debe ser el campo de una clase o estructura. Las variables locales no se pueden declarar como volatile. Ejemplo El ejemplo siguiente muestra cmo declarar una variable de campo pblica como volatile.

// csharp_volatile.cs // compile with: /target:library class Test { public volatile int i; Test(int _i) { i = _i; } }

MCT: Luis Dueas

Pag 53 de 148

.NET 2 C# .NET

Tipos de instrucciones
Este captulo describe las instrucciones de C# que se pueden utilizar en un programa. Salvo que se indique otra cosa, las instrucciones se ejecutan secuencialmente. C# dispone de las siguientes categoras de instrucciones:

Categora

Palabras clave de C#

Instrucciones de seleccin Instrucciones de iteracin Instrucciones de salto Instrucciones de control de excepciones Checked y unchecked Instruccin fixed Instruccin lock

if, else, switch, case do, for, foreach, in, while break, continue, default, goto, return, yield throw, try-catch, try-finally, try-catch-finally checked, unchecked fixed lock

Instrucciones de seleccin
Una instruccin de seleccin hace que el control del programa se transfiera a un determinado punto del flujo de ejecucin dependiendo de que cierta condicin sea true o no.

if-else
La instruccin if selecciona una instruccin para ejecucin en base al valor de una expresin Boolean. En el ejemplo siguiente un indicador Boolean flagCheck se establece en true y, a continuacin, se protege en la instruccin if. El resultado es: The flag is set to true.

bool flagCheck = true; if (flagCheck == true) { Console.WriteLine("The flag is set to true."); } else { Console.WriteLine("The flag is set to false."); }
Comentarios Si la expresin en el parntesis se evala como true, a continuacin se ejecuta la instruccin

Console.WriteLine("The boolean flag is set to ture."); . Despus de ejecutar


la instruccin if, el control se transfiere a la siguiente instruccin. Else no se ejecuta en este ejemplo. Si se desea ejecutar ms de una instruccin, es posible ejecutar varias instrucciones en forma condicional al incluirlas en bloques mediante {}, al igual que en el ejemplo anterior.

MCT: Luis Dueas

Pag 54 de 148

.NET 2 C# .NET
Las instrucciones que se van a ejecutar como resultado de comprobar la condicin pueden ser de cualquier tipo, incluida otra instruccin if anidada dentro de la instruccin if original. En las instrucciones if anidadas, la clusula else pertenece a la ltima instruccin if que no tiene una clusula else correspondiente. Por ejemplo:

if (x > 10) if (y > 20) Console.Write("Statement_1"); else Console.Write("Statement_2"); En este ejemplo, se mostrar Statement_2 si la condicin (y > 20) se evala como false. No obstante, si desea asociar Statement_2 a la condicin (x >10), utilice llaves: if (x > 10) { if (y > 20) Console.Write("Statement_1"); } else Console.Write("Statement_2"); En este caso, se mostrar Statement_2 si la condicin (x > 10) se evala como false.
Ejemplo 1 En este ejemplo, se escribe un carcter desde el teclado y el programa comprueba si se trata de un carcter alfabtico. En ese caso, comprueba si es minscula o mayscula. En cada caso, se muestra el mensaje apropiado.

// statements_if_else.cs // if-else example using System; class IfTest { static void Main() { Console.Write("Enter a character: "); char c = (char)Console.Read(); if (Char.IsLetter(c)) { if (Char.IsLower(c)) { Console.WriteLine("The character is lowercase."); } else { Console.WriteLine("The character is uppercase."); } } else { Console.WriteLine("Not an alphabetic character."); } } }
Resultado

MCT: Luis Dueas

Pag 55 de 148

.NET 2 C# .NET
Resultados del ejemplo

Enter a character: 2 The character is not an alphabetic character.


A continuacin se ofrece otro ejemplo: Ejecucin N 2:

Enter a character: A The character is uppercase.


Ejecucin N 3:

Enter a character: h The character is lowercase.


Tambin es posible extender la instruccin if de modo que puedan controlarse varias condiciones, mediante la construccin else-if siguiente:

if (Condition_1) { // Statement_1; } else if (Condition_2) { // Statement_2; } else if (Condition_3) { // Statement_3; } else { // Statement_n; }
Ejemplo 2 Este ejemplo comprueba si el carcter especificado es una letra minscula, mayscula o un nmero. En cualquier otro caso, se tratar de un carcter no alfanumrico. El programa utiliza la anterior estructura else-if en escalera.

// statements_if_else2.cs // else-if using System; public class IfTest { static void Main() { Console.Write("Enter a character: "); char c = (char)Console.Read(); if (Char.IsUpper(c)) { Console.WriteLine("Character is uppercase."); } else if (Char.IsLower(c)) { Console.WriteLine("Character is lowercase."); } else if (Char.IsDigit(c))

MCT: Luis Dueas

Pag 56 de 148

.NET 2 C# .NET
{ Console.WriteLine("Character is a number."); } else { Console.WriteLine("Character is not alphanumeric."); } } }
Resultado

E
Resultados del ejemplo

Enter a character: E The character is uppercase.


A continuacin se ofrecen otros ejemplos de ejecuciones: Ejecucin N 2:

Enter a character: e The character is lowercase.


Ejecucin N 3:

Enter a character: 4 The character is a number.


Ejecucin N 4:

Enter a character: $ The character is not alphanumeric.

switch
La instruccin switch es una instruccin de control que controla mltiples selecciones y enumeraciones pasando el control a una de las instrucciones case de su cuerpo, como se muestra en el ejemplo siguiente:

int caseSwitch = 1; switch (caseSwitch) { case 1: Console.WriteLine("Case 1"); break; case 2: Console.WriteLine("Case 2"); break; default: Console.WriteLine("Default case"); break; }
Comentarios El control se transfiere a la instruccin case que coincide con el valor del modificador. La instruccin switch puede incluir cualquier nmero de instancias case, sin embargo dos instrucciones case nunca pueden tener el mismo valor. La ejecucin del cuerpo de la instruccin empieza en la instruccin seleccionada y contina hasta que la instruccin break transfiere el control fuera del cuerpo case. Es necesario introducir una instruccin de salto como break

MCT: Luis Dueas

Pag 57 de 148

.NET 2 C# .NET
despus de cada bloque case, incluido el ltimo bloque, se trate de una instruccin case o de una instruccin default. Con una excepcin, (a diferencia de la instruccin switch de C++), C# no admite el paso implcito de una etiqueta case a otra. Esta excepcin se produce si una instruccin case no tiene ningn cdigo. Si ninguna expresin case coincide con el valor de la instruccin switch, entonces el control se transfiere a las instrucciones que siguen la etiqueta default opcional. Si no existe ninguna etiqueta default, el control se transfiere fuera de la instruccin switch. Ejemplo

// statements_switch.cs using System; class SwitchTest { static void Main() { Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large"); Console.Write("Please enter your selection: "); string s = Console.ReadLine(); int n = int.Parse(s); int cost = 0; switch(n) { case 1: cost += 25; break; case 2: cost += 25; goto case 1; case 3: cost += 50; goto case 1; default: Console.WriteLine("Invalid selection. Please select 1, 2, or 3."); break; } if (cost != 0) { Console.WriteLine("Please insert {0} cents.", cost); } Console.WriteLine("Thank you for your business."); } }
Entrada

2
Resultados del ejemplo

Coffee sizes: 1=Small 2=Medium 3=Large Please enter your selection: 2 Please insert 50 cents. Thank you for your business.
El siguiente ejemplo muestra que se permite el paso de una etiqueta case a otra para etiquetas case vacas.

MCT: Luis Dueas

Pag 58 de 148

.NET 2 C# .NET
// statements_switch2.cs using System; class SwitchTest { static void Main() { int n = 2; switch(n) { case 1: case 2: case 3: Console.WriteLine("It's 1, 2, or 3."); break; default: Console.WriteLine("Not sure what it is."); break; } } }
Resultados

It's 1, 2, or 3.
Descripcin del cdigo

En el ejemplo anterior, se utiliz una variable de tipo integral, n, para los casos de la instruccin switch. Observe que tambin se puede utilizar la variable de cadena, s, directamente. En ese caso, la estructura switch puede presentar la siguiente forma:

switch(s) { case "1": // ... case "2": // ... }

Instrucciones de iteracin
Las instrucciones de iteracin permiten crear bucles. En un bucle, las instrucciones internas se ejecutan un determinado nmero de veces, segn el criterio de terminacin del bucle. Estas instrucciones se ejecutan en orden, salvo cuando se encuentra una instruccin de salto.

do
La instruccin do ejecuta una instruccin o un bloque de instrucciones entre {} repetidamente hasta que una expresin especificada se evale como false. En el ejemplo siguiente las instrucciones de bucle do se ejecutan con la condicin de que la variable y sea menor que 5. Ejemplo

// statements_do.cs using System; public class TestDoWhile

MCT: Luis Dueas

Pag 59 de 148

.NET 2 C# .NET
{ public static void Main () { int x = 0; do { Console.WriteLine(x); x++; } while (x < 5); } }
Resultados

0 1 2 3 4

for
El bucle for ejecuta una instruccin o un bloque de instrucciones repetidamente hasta que una determinada expresin se evala como false. El bucle for es til para recorrer en iteracin matrices y para procesar secuencialmente. En el ejemplo siguiente el valor de int i se escribe en la consola y el valor de i se va incrementando en 1 en el bucle. Ejemplo

// statements_for.cs // for loop using System; class ForLoopTest { static void Main() { for (int i = 1; i <= 5; i++) { Console.WriteLine(i); } } }
Resultados

1 2 3 4 5
Comentarios La instruccin for ejecuta la instruccin o instrucciones internas repetidamente del siguiente modo:

Primero, se evala el valor inicial de la variable i. A continuacin, mientras el valor de i es menor que 5, la condicin se evala como true, se ejecuta la instruccin Console.WriteLine y se reevala i. Cuando i es mayor que 5, la condicin se convierte en false y el control se transfiere fuera del bucle.

MCT: Luis Dueas

Pag 60 de 148

.NET 2 C# .NET
Puesto que la comprobacin de la expresin condicional tiene lugar antes de la ejecucin del bucle, las instrucciones internas de un bucle for pueden no llegar a ejecutarse. Todas las expresiones de la instruccin for son opcionales; por ejemplo, la siguiente instruccin se utiliza para crear un bucle infinito:

for (;;) { // ... }

foreach, in
La instruccin foreach repite un grupo de instrucciones incluidas en el bucle para cada elemento de una matriz o de un objeto collection. La instruccin foreach se utiliza para recorrer en iteracin una coleccin de elementos y obtener la informacin deseada, pero no se debe utilizar para cambiar el contenido de la coleccin, ya que se pueden producir efectos secundarios imprevisibles. Comentarios Las instrucciones del bucle siguen ejecutndose para cada elemento de la matriz o la coleccin. Cuando ya se han recorrido todos los elementos de la coleccin, el control se transfiere a la siguiente instruccin fuera del bloque foreach. Ejemplo En este ejemplo, foreach se utiliza para mostrar el contenido de una matriz de enteros.

// cs_foreach.cs class ForEachTest { static void Main(string[] args) { int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 }; foreach (int i in fibarray) { System.Console.WriteLine(i); } } }
Resultados

0 1 2 3 5 8 13

while
La instruccin while ejecuta una instruccin o un bloque de instrucciones repetidamente hasta que una expresin especificada se evala como false. Ejemplo

// statements_while.cs using System; class WhileTest

MCT: Luis Dueas

Pag 61 de 148

.NET 2 C# .NET
{ static void Main() { int n = 1; while (n < 6) { Console.WriteLine("Current value of n is {0}", n); n++; } } }
Resultados

Current value of n is 1 Current value of n is 2 Current value of n is 3 Current value of n is 4 Current value of n is 5 // statements_while_2.cs using System; class WhileTest { static void Main() { int n = 1; while (n++ < 6) { Console.WriteLine("Current value of n is {0}", n); } } }
Resultados

Current value of n is 2 Current value of n is 3 Current value of n is 4 Current value of n is 5 Current value of n is 6
Como la comprobacin de la expresin while tiene lugar antes de la ejecucin del bucle, las instrucciones internas de un bucle while pueden no llegar a ejecutarse. Esto es diferente del bucle do que se ejecuta una o varias veces. Un bucle while se puede terminar cuando una instruccin break, goto, return o throw transfiere el control fuera del bucle. Para pasar el control a la siguiente iteracin sin salir del bucle, use la instruccin continue. Observe la diferencia en los resultados de los tres ejemplos anteriores con relacin a dnde se incrementa int n. En el ejemplo siguiente no se genera ningn resultado.

// statements_while_3.cs // no output is generated using System; class WhileTest { static void Main() { int n = 5;

MCT: Luis Dueas

Pag 62 de 148

.NET 2 C# .NET
while (++n < 6) { Console.WriteLine("Current value of n is {0}", n); } } }

Instrucciones de salto
La alteracin del flujo secuencial normal de un programa se consigue mediante instrucciones de salto, las cuales producen una transferencia inmediata del control del programa. Las siguientes palabras clave se utilizan en instrucciones de salto:

break
La instruccin break permite terminar el bucle envolvente ms cercano o la instruccin switch en la cual aparece. El control se transfiere a la instruccin que sigue a la instruccin terminada, si existe alguna. Ejemplo En este ejemplo, la instruccin condicional contiene un contador que se supone que cuenta de 1 a 100; sin embargo, la instruccin break termina el bucle tras 4 iteraciones.

// statements_break.cs using System; class BreakTest { static void Main() { for (int i = 1; i <= 100; i++) { if (i == 5) { break; } Console.WriteLine(i); } } }
Resultados

1 2 3 4
Este ejemplo muestra el uso de break en una instruccin switch.

// statements_break2.cs // break and switch using System; class Switch { static void Main() {

MCT: Luis Dueas

Pag 63 de 148

.NET 2 C# .NET
Console.Write("Enter your selection (1, 2, or 3): "); string s = Console.ReadLine(); int n = Int32.Parse(s); switch (n) { case 1: Console.WriteLine("Current value is {0}", 1); break; case 2: Console.WriteLine("Current value is {0}", 2); break; case 3: Console.WriteLine("Current value is {0}", 3); break; default: Console.WriteLine("Sorry, invalid selection."); break; } } }
Entrada

1
Resultados del ejemplo

Enter your selection (1, 2, or 3): 1 Current value is 1

continue
La instruccin continue transfiere el control a la siguiente iteracin de la instruccin de iteracin envolvente donde aparece. Ejemplo En este ejemplo, se inicializa un contador que cuenta de 1 a 10. Utilizando la instruccin continue con la expresin (i < 9), se omiten las instrucciones situadas entre continue y el final del cuerpo del bucle for.

// statements_continue.cs using System; class ContinueTest { static void Main() { for (int i = 1; i <= 10; i++) { if (i < 9) { continue; } Console.WriteLine(i);

MCT: Luis Dueas

Pag 64 de 148

.NET 2 C# .NET
} } }
Resultados

9 10

goto
La instruccin goto transfiere el control del programa directamente a una instruccin identificada por una etiqueta. Comentarios Un uso habitual de goto consiste en transferir el control a una etiqueta switch-case especfica o a la etiqueta predeterminada de una instruccin switch. La instruccin goto tambin es til para salir de bucles de varios niveles de anidamiento. Ejemplo El ejemplo siguiente muestra cmo utilizar goto en una instruccin switch.

// statements_goto_switch.cs using System; class SwitchTest { static void Main() { Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large"); Console.Write("Please enter your selection: "); string s = Console.ReadLine(); int n = int.Parse(s); int cost = 0; switch (n) { case 1: cost += 25; break; case 2: cost += 25; goto case 1; case 3: cost += 50; goto case 1; default: Console.WriteLine("Invalid selection."); break; } if (cost != 0) { Console.WriteLine("Please insert {0} cents.", cost);

MCT: Luis Dueas

Pag 65 de 148

.NET 2 C# .NET
} Console.WriteLine("Thank you for your business."); } }
Entrada

2
Resultados del ejemplo

Coffee sizes: 1=Small 2=Medium 3=Large Please enter your selection: 2 Please insert 50 cents. Thank you for your business.
El siguiente ejemplo muestra el uso de goto para salir de un conjunto de bucles anidados.

// statements_goto.cs // Nested search loops using System; public class GotoTest1 { static void Main() { int x = 200, y = 4; int count = 0; string[,] array = new string[x, y]; // Initialize the array: for (int i = 0; i < x; i++) for (int j = 0; j < y; j++) array[i, j] = (++count).ToString(); // Read input: Console.Write("Enter the number to search for: "); // Input a string: string myNumber = Console.ReadLine(); // Search: for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { if (array[i, j].Equals(myNumber)) { goto Found; } } } Console.WriteLine("The number {0} was not found.", myNumber); goto Finish; Found: Console.WriteLine("The number {0} is found.", myNumber); Finish: Console.WriteLine("End of search."); } }
Entrada

44
Resultados del ejemplo

Enter the number to search for: 44 The number 44 is found. End of search.

return
La instruccin return termina la ejecucin del mtodo en el que aparece y devuelve el control al mtodo que realiz la llamada. Tambin puede devolver un valor opcional. Si el mtodo es del tipo void, la instruccin return se puede omitir. Ejemplo En el siguiente ejemplo, el mtodo A() devuelve la variable Area como un valor de tipo double.

// statements_return.cs using System; class ReturnTest { static double CalculateArea(int r) { double area = r * r * Math.PI; return area; } static void Main() {

MCT: Luis Dueas

Pag 66 de 148

.NET 2 C# .NET
int radius = 5; Console.WriteLine("The area is {0:0.00}", CalculateArea(radius)); } }
Resultados

The area is 78.54

Instrucciones para el control de excepciones


C# incorpora mecanismos para el tratamiento de las situaciones anmalas, denominadas excepciones, que pueden producirse durante la ejecucin de un programa. Estas excepciones se controlan mediante cdigo situado fuera del flujo normal de control. Esta seccin describe los siguientes temas sobre el control de excepciones:

throw
La instruccin throw se utiliza para sealizar la aparicin de una situacin anmala (excepcin) durante la ejecucin del programa. Comentarios La excepcin producida es un objeto cuya clase se deriva de System.Exception, por ejemplo:

class MyException : System.Exception { } // ... throw new MyException();


Normalmente, la instruccin throw se utiliza con las instrucciones try-catch o try-finally. Cuando se produce una excepcin, el programa busca la instruccin catch que controla esa excepcin. Tambin se puede volver a producir una excepcin detectada mediante la instruccin throw. Para obtener ms informacin, incluidos ejemplos, vea try-catch e Producir excepciones. Ejemplo Este ejemplo muestra cmo provocar una excepcin mediante la instruccin throw.

// throw example using System; public class ThrowTest { static void Main() { string s = null; if (s == null) { throw new ArgumentNullException(); } Console.Write("The string s is null"); // not executed

MCT: Luis Dueas

Pag 67 de 148

.NET 2 C# .NET
} }
Resultados Se produce la excepcin ArgumentNullException.

try-catch
La instruccin try-catch consta de un bloque try seguido de una o ms clusulas catch, las cuales especifican controladores para diferentes excepciones. Comentarios El bloque try contiene el cdigo protegido que puede causar la excepcin. Este bloque se ejecuta hasta que se produce una excepcin o hasta completarse satisfactoriamente. Por ejemplo, el siguiente intento de convertir un objeto null provoca la excepcin NullReferenceException:

object o2 = null; try { int i2 = (int)o2; // Error }


La clusula catch se puede utilizar sin argumentos, en cuyo caso captura cualquier tipo de excepcin y se conoce como clusula catch general. Tambin puede aceptar un argumento de objeto derivado de System.Exception, en cuyo caso trata una excepcin especfica. Por ejemplo:

catch (InvalidCastException e) { }
Es posible utilizar ms de una clusula catch especfica en la misma instruccin try-catch. En este caso, el orden de las clusulas catch es importante, ya que las clusulas catch se examinan por orden. Las excepciones ms especficas se capturan antes que las menos especficas. Se puede utilizar una instruccin throw en el bloque catch para volver a producir la excepcin, la cual ha sido capturada por la instruccin catch. Por ejemplo:

catch (InvalidCastException e) { throw (e); // Rethrowing exception e }


Si desea volver a producir la excepcin que est siendo actualmente controlada por una clusula catch sin parmetros, use la instruccin throw sin argumentos. Por ejemplo:

catch { throw; }
Dentro de un bloque try, inicialice slo variables declaradas en su interior; en caso contrario, puede producirse una excepcin antes de que se complete la ejecucin del bloque. Por ejemplo, en el siguiente ejemplo de cdigo, la variable x se inicializa dentro del bloque try. Al intentar utilizar esta variable fuera del bloque try en la instruccin Write(x), se generar el siguiente error del compilador: Uso de variable local no asignada.

MCT: Luis Dueas

Pag 68 de 148

.NET 2 C# .NET
static void Main() { int x; try { // Don't initialize this variable here. x = 123; } catch { } // Error: Use of unassigned local variable 'x'. Console.Write(x); }
Ejemplo En este ejemplo, el bloque try contiene una llamada al mtodo MyMethod(), que puede producir una excepcin. La clusula catch contiene el controlador de excepciones, el cual simplemente muestra un mensaje en la pantalla. Cuando se realiza la llamada a la instruccin throw desde dentro de MyMethod, el sistema busca la instruccin catch y muestra el mensaje Exception

caught. // try_catch_example.cs using System; class MainClass { static void ProcessString(string s) { if (s == null) { throw new ArgumentNullException(); } } static void Main() { try { string s = null; ProcessString(s); } catch (Exception e) { Console.WriteLine("{0} Exception caught.", e); } } }
Resultados del ejemplo

System.ArgumentNullException: Value cannot be null. at MainClass.Main() Exception caught.


En este ejemplo, se utilizan dos instrucciones catch. La excepcin ms especfica, que aparece en primer lugar, se captura primero.

MCT: Luis Dueas

Pag 69 de 148

.NET 2 C# .NET
// try_catch_ordering_catch_clauses.cs using System; class MainClass { static void ProcessString(string s) { if (s == null) { throw new ArgumentNullException(); } } static void Main() { try { string s = null; ProcessString(s); } // Most specific: catch (ArgumentNullException e) { Console.WriteLine("{0} First exception caught.", e); } // Least specific: catch (Exception e) { Console.WriteLine("{0} Second exception caught.", e); } } }
Resultados del ejemplo

System.ArgumentNullException: Value cannot be null. at MainClass.Main() First exception caught.


Comentarios En el ejemplo anterior, si empieza con la clusula catch menos especfica, aparecer el mensaje de error: A previous catch clause already catches all exceptions of this or

a super type ('System.Exception')


No obstante, para capturar la excepcin menos especfica, debe reemplazar la instruccin throw por la siguiente:

throw new Exception();

try-finally
El bloque finally es til para limpiar cualquier recurso asignado en el bloque try, as como tambin para ejecutar cualquier cdigo que deba ejecutarse incluso si hay una excepcin. El control se transfiere siempre al bloque finally independientemente de cmo finalice el bloque try. Comentarios

MCT: Luis Dueas

Pag 70 de 148

.NET 2 C# .NET
Mientras que catch se utiliza para controlar las excepciones que se producen en un bloque de instrucciones, finally se emplea para asegurar la ejecucin de un bloque de instrucciones sin importar cmo finaliza el bloque try anterior. Ejemplo En este ejemplo, existe una instruccin de conversin no vlida que produce una excepcin. Cuando se ejecuta el programa, se obtiene un mensaje de error en tiempo de ejecucin, pero la clusula finally se ejecuta de todas formas y muestra el resultado.

// try-finally using System; public class MainClass { static void Main() { int i = 123; string s = "Some string"; object o = s; try { // Invalid conversion; o contains a string not an int i = (int)o; } finally { Console.Write("i = {0}", i); } } }
Comentarios El ejemplo anterior hace que se produzca la excepcin System.InvalidCastException. A pesar de que se captur una excepcin, la instruccin de salida incluida en el bloque finally se ejecutar de todas formas, es decir:

i = 123

try-catch-finally
Un uso comn de catch y finally consiste en obtener y utilizar recursos en un bloque try, tratar circunstancias excepcionales en el bloque catch y liberar los recursos en el bloque finally. Ejemplo

// try_catch_finally.cs using System; public class EHClass { static void Main() { try

MCT: Luis Dueas

Pag 71 de 148

.NET 2 C# .NET
{ Console.WriteLine("Executing the try statement."); throw new NullReferenceException(); } catch (NullReferenceException e) { Console.WriteLine("{0} Caught exception #1.", e); } catch { Console.WriteLine("Caught exception #2."); } finally { Console.WriteLine("Executing finally block."); } } }
Resultados del ejemplo

Executing the try statement. System.NullReferenceException: Object reference not set to an instance of an object. at EHClass.Main() Caught exception #1. Executing finally block.

Checked y Unchecked
Las instrucciones de C# se pueden ejecutar en un contexto comprobado (checked) o no comprobado (unchecked). En un contexto comprobado, el desbordamiento aritmtico produce una excepcin. En un contexto no comprobado, se hace caso omiso del desbordamiento aritmtico y el resultado se trunca.

checked

Especifica un contexto comprobado. Especifica un contexto no comprobado.

unchecked

Si no se especifica checked ni unchecked, el contexto predeterminado depende de factores externos tales como las opciones del compilador. La comprobacin del desbordamiento afecta a las siguientes operaciones:

++

Expresiones que utilizan los siguientes operadores predefinidos con tipos integrales: - (unario) + * /

Conversiones numricas explcitas entre tipos integrales.

La opcin del compilador /checked permite especificar un contexto checked o unchecked para todas las instrucciones aritmticas de enteros que no se encuentran explcitamente en el mbito de una palabra clave checked o unchecked.

MCT: Luis Dueas

Pag 72 de 148

.NET 2 C# .NET

checked
La palabra clave checked se utiliza con el fin de habilitar explcitamente la comprobacin de desbordamiento para operaciones aritmticas y conversiones de tipo integral. Comentarios De forma predeterminada, si una expresin genera un valor que est fuera del intervalo del tipo de destino, las expresiones constantes producen errores en tiempo de compilacin y las expresiones no constantes se evalan en tiempo de ejecucin y producen excepciones. Sin embargo, la palabra clave checked se puede utilizar para habilitar la comprobacin si las opciones del compilador o configuracin del entorno la suprimen globalmente. Vea los ejemplos de unchecked en los ejemplos de uso de la palabra clave unchecked. Ejemplo Este ejemplo muestra cmo utilizar checked para una expresin no constante. El desbordamiento se notifica en tiempo de ejecucin.

// statements_checked.cs using System; class OverFlowTest { static short x = 32767; // Max short value static short y = 32767; // Using a checked expression static int CheckedMethod() { int z = 0; try { z = checked((short)(x + y)); } catch (System.OverflowException e) { Console.WriteLine(e.ToString()); } return z; } static void Main() { Console.WriteLine("Checked output value is: {0}", CheckedMethod()); } }
Resultados del ejemplo

System.OverflowException: Arithmetic operation resulted in an overflow. at OverFlowTest.CheckedMethod() Checked output value is: 0

MCT: Luis Dueas

Pag 73 de 148

.NET 2 C# .NET

unchecked
La palabra clave unchecked se utiliza con el fin de suprimir la comprobacin de desbordamiento para operaciones aritmticas y conversiones de tipo integral. Comentarios En un contexto no comprobado (unchecked), si una expresin produce un valor fuera del intervalo del tipo de destino, el resultado se trunca. Por ejemplo:

unchecked { int val = 2147483647 * 2; }


Como el clculo anterior se realiza en un bloque unchecked, se pasa por alto que el resultado es demasiado grande para un valor entero y se asigna a val el valor -2. De forma predeterminada, se habilita la deteccin del desbordamiento, que tiene el mismo efecto que utilizar checked. En el ejemplo anterior, si se hubiera omitido unchecked, ocurrira un error de compilacin porque la expresin utiliza constantes y el resultado se conoce en tiempo de compilacin. La palabra clave unchecked tambin suprime la deteccin del desbordamiento para expresiones no constantes, que de lo contrario producen una excepcin OverflowException en tiempo de ejecucin. La palabra clave unchecked tambin se puede utilizar como operador, de la manera siguiente:

public int UncheckedAdd(int a, int b) { return unchecked(a + b); }


Ejemplo Este ejemplo muestra cmo utilizar la instruccin unchecked, utilizando unchecked con expresiones constantes.

// statements_unchecked.cs using System; class TestClass { const int x = 2147483647; // Max int const int y = 2; static void Main() { int z; unchecked { z = x * y; } Console.WriteLine("Unchecked output value: {0}", z); } }
Resultados

Unchecked output value: -2

MCT: Luis Dueas

Pag 74 de 148

.NET 2 C# .NET

fixed
La instruccin fixed evita que el recolector de elementos no utilizados vuelva a ubicar una variable mvil. La instruccin fixed slo se permite en un contexto unsafe. Tambin se puede utilizar Fixed para crear bferes de tamao fijo. Comentarios La instruccin fixed crea un puntero a una variable administrada y "fija" esa variable durante la ejecucin de la instruccinstatement. Sin la instruccin fixed, los punteros a variables administradas mviles seran de poca utilidad, ya que el proceso de recoleccin de elementos no utilizados podra cambiar la ubicacin de las variables de forma impredecible. El compilador de C# slo permite asignar un puntero a una variable administrada en una instruccin fixed.

// assume class Point { public int x, y; } // pt is a managed variable, subject to garbage collection. Point pt = new Point(); // Using fixed allows the address of pt members to be // taken, and "pins" pt so it isn't relocated. fixed ( int* p = &pt.x ) { *p = 1; }
Un puntero se puede inicializar con la direccin de una matriz o de una cadena:

fixed (int* p = arr) ... // equivalent to p = &arr[0] fixed (char* p = str) ... // equivalent to p = &str[0]
Se pueden inicializar varios punteros a la vez, siempre que sean del mismo tipo:

fixed (byte* ps = srcarray, pd = dstarray) { ... }


Para inicializar punteros de diferente tipo, simplemente anide instrucciones fixed:

fixed (int* p1 = &p.x) { fixed (double* p2 = &array[5]) { // Do something with p1 and p2. } }
Despus de ejecutar el cdigo de la instruccin, se libera cualquier variable anteriormente fijada y queda sujeta al proceso de recoleccin de elementos no utilizados. Por lo tanto, no se debe apuntar a esas variables desde fuera de la instruccin fixed.

Nota

Los punteros inicializados en instrucciones fixed no se pueden modificar.

MCT: Luis Dueas

Pag 75 de 148

.NET 2 C# .NET
En el modo no seguro (unsafe), se puede asignar memoria a la pila, donde no est sometida a recoleccin de elementos no utilizados y, por lo tanto, no necesita fijarse. Para obtener ms informacin, vea stackalloc (Referencia de C#). Ejemplo

// statements_fixed.cs // compile with: /unsafe using System; class Point { public int x, y; } class FixedTest { // Unsafe method: takes a pointer to an int. unsafe static void SquarePtrParam (int* p) { *p *= *p; } unsafe static void Main() { Point pt = new Point(); pt.x = 5; pt.y = 6; // Pin pt in place: fixed (int* p = &pt.x) { SquarePtrParam (p); } // pt now unpinned Console.WriteLine ("{0} {1}", pt.x, pt.y); } }
Resultados

25 6

lock
La palabra clave lock marca un bloque de instrucciones como una seccin crucial, para lo cual utiliza el bloqueo de exclusin mutua de un objeto, la ejecucin de una instruccin y, posteriormente, la liberacin del bloqueo. La instruccin presenta la siguiente forma:

Object thisLock = new Object(); lock (thisLock) { // Critical code section }


Comentarios

MCT: Luis Dueas

Pag 76 de 148

.NET 2 C# .NET
La instruccin lock permite garantizar que un subproceso no va a entrar en una seccin crucial de cdigo mientras otro subproceso ya se encuentre en ella. Si otro subproceso intenta entrar en un cdigo bloqueado, esperar, o se bloquear, hasta que el objeto se libere. La palabra clave lock llama a Enter al principio del bloque y a Exit al final del bloque. En general evite bloquear un tipo public o instancias que estn fuera del control de su cdigo. Las construcciones comunes lock (this), lock (typeof (MyType)) y lock ("myLock") incumplen esta instruccin:

lock (this) se convierte en un problema si la instancia es accesible pblicamente. lock (typeof (MyType)) se convierte en un problema si MyType es accesible
pblicamente.

lock(myLock) se convierte en un problema puesto que cualquier otro cdigo del


proceso que utilice la misma cadena, compartir el mismo bloqueo.

El procedimiento recomendado es definir un objeto un objeto private para realizar el bloqueo o una variable de objeto private shared para proteger los datos comunes a todas las instancias. Ejemplo El siguiente ejemplo muestra un uso simple de subprocesos en C#.

// statements_lock.cs using System; using System.Threading; class ThreadTest { public void RunMe() { Console.WriteLine("RunMe called"); } static void Main() { ThreadTest b = new ThreadTest(); Thread t = new Thread(b.RunMe); t.Start(); } }
Resultados

RunMe called
El siguiente ejemplo utiliza subprocesos y lock. Con el uso de la instruccin lock, el bloque de instrucciones se convierte en una seccin crtica y balance nunca tomar un valor negativo.

// statements_lock2.cs using System; using System.Threading; class Account { private Object thisLock = new Object(); int balance; Random r = new Random(); public Account(int initial)

MCT: Luis Dueas

Pag 77 de 148

.NET 2 C# .NET
{ balance = initial; } int Withdraw(int amount) { // This condition will never be true unless the lock statement // is commented out: if (balance < 0) { throw new Exception("Negative Balance"); } // Comment out the next line to see the effect of leaving out the lock keyword: lock(thisLock) { if (balance >= amount) { Console.WriteLine("Balance before Withdrawal : " + balance); Console.WriteLine("Amount to Withdraw : -" + amount); balance = balance - amount; Console.WriteLine("Balance after Withdrawal : " + balance); return amount; } else { return 0; // transaction rejected } } } public void DoTransactions() { for (int i = 0; i < 100; i++) { Withdraw(r.Next(1, 100)); } } } class Test { static void Main() { Thread[] threads = new Thread[10]; Account acc = new Account(1000); for (int i = 0; i < 10; i++) { Thread t = new Thread(new ThreadStart(acc.DoTransactions)); threads[i] = t; } for (int i = 0; i < 10; i++) { threads[i].Start(); } } }

MCT: Luis Dueas

Pag 78 de 148

.NET 2 C# .NET

Parmetros de mtodos
Si un parmetro se declara para un mtodo sin ref u out, se le puede asociar un valor. Ese valor se puede cambiar en el mtodo, pero el cambio se perder cuando se devuelva el control al procedimiento que realiz la llamada. Si utiliza palabras clave de parmetros de mtodo en la declaracin del parmetro, puede modificar ese comportamiento. Esta seccin describe las palabras clave que puede utilizar para declarar parmetros de mtodos:

params
La palabra clave params permite especificar un parmetro de mtodo que acepta un nmero variable de argumentos. No se permiten parmetros adicionales despus de la palabra clave params, ni varias palabras clave params en una misma declaracin de mtodo. Ejemplo

// cs_params.cs using System; public class MyClass { public static void UseParams(params int[] list) { for (int i = 0 ; i < list.Length; i++) { Console.WriteLine(list[i]); } Console.WriteLine(); } public static void UseParams2(params object[] list) { for (int i = 0 ; i < list.Length; i++) { Console.WriteLine(list[i]); } Console.WriteLine(); } static void Main() { UseParams(1, 2, 3); UseParams2(1, 'a', "test"); // An array of objects can also be passed, as long as // the array type matches the method being called. int[] myarray = new int[3] {10,11,12}; UseParams(myarray); } }
Resultados

1 2 3 1 a test 10 11 12

MCT: Luis Dueas

Pag 79 de 148

.NET 2 C# .NET

ref
La palabra clave ref produce argumentos que se van a pasar por referencia. El efecto es que cualquier cambio que se realice en el parmetro dentro del mtodo se reflejar en esa variable cuando se devuelva el control al mtodo que realiz la llamada. Para utilizar un parmetro ref, la definicin de mtodo y el mtodo de llamada deben utilizar explcitamente la palabra clave ref. Por ejemplo:

class RefExample { static void Method(ref int i) { i = 44; } static void Main() { int val = 0; Method(ref val); // val is now 44 } }
Para pasar un argumento a un parmetro ref, primero debe inicializarse. Esto es diferente de out, cuyo argumento no tiene que inicializarse explcitamente antes de pasarlo. Aunque ref y out se tratan de manera diferente en tiempo de ejecucin, se tratan de la misma manera en tiempo de compilacin. Por consiguiente no se pueden sobrecargar los mtodos si un mtodo toma un argumento ref y el otro toma un argumento out. Por ejemplo, estos dos mtodos son idnticos en lo referente a la compilacin, por lo que este cdigo no se compilar:

class CS0663_Example { // compiler error CS0663: "cannot define overloaded // methods that differ only on ref and out" public void SampleMethod(ref int i) { } public void SampleMethod(out int i) { } }
Sin embargo, se puede realizar la sobrecarga si un mtodo toma un argumento ref u out y el otro no utiliza ninguno de los dos, de la manera siguiente:

class RefOutOverloadExample { public void SampleMethod(int i) { } public void SampleMethod(ref int i) { } }


Comentarios Las propiedades no son variables y, por consiguiente, no se pueden pasar como parmetros ref. Ejemplo Como se mostr anteriormente, el paso de tipos de valor por referencia es til, pero ref tambin es til para pasar los tipos de referencia. Esto permite a los mtodos llamados modificar el objeto

MCT: Luis Dueas

Pag 80 de 148

.NET 2 C# .NET
al que se refiere la referencia porque la propia referencia se pasa por referencia. El ejemplo siguiente muestra que cuando un tipo de referencia se pasa como parmetro ref, se puede cambiar el objeto mismo.

class RefRefExample { static void Method(ref string s) { s = "changed"; } static void Main() { string str = "original"; Method(ref str); // str is now "changed" } }

out
La palabra clave out produce argumentos que se van a pasar por referencia. Esto es similar a la palabra clave ref, excepto en que ref requiere que se inicialice la variable antes de pasarla. Utilizar un parmetro out, la definicin de mtodo y el mtodo de llamada deben utilizar explcitamente la palabra clave out. Por ejemplo:

class OutExample { static void Method(out int i) { i = 44; } static void Main() { int value; Method(out value); // value is now 44 } }
Aunque las variables pasadas como argumentos out no tienen que inicializarse antes de pasarlas, el mtodo de llamada es necesario para asignar un valor antes de que el mtodo devuelva un valor. Las palabras clave ref y out se tratan de manera diferente en tiempo de ejecucin, pero se tratan del mismo modo en tiempo de compilacin. Por consiguiente no se pueden sobrecargar los mtodos si un mtodo toma un argumento ref y el otro toma un argumento out. Por ejemplo, estos dos mtodos son idnticos en lo referente a la compilacin, por lo que este cdigo no se compilar:

class CS0663_Example {

MCT: Luis Dueas

Pag 81 de 148

.NET 2 C# .NET
// compiler error CS0663: "cannot define overloaded // methods that differ only on ref and out" public void SampleMethod(out int i) { } public void SampleMethod(ref int i) { } }
Sin embargo, se puede realizar la sobrecarga si un mtodo toma un argumento ref u out y el otro no utiliza ninguno de los dos, de la manera siguiente:

class RefOutOverloadExample { public void SampleMethod(int i) { } public void SampleMethod(out int i) { } }


Comentarios Las propiedades no son variables y, por consiguiente, no se pueden pasar como parmetros out. Ejemplo Declarar un mtodo como out es til cuando se desea que devuelva varios valores. Un mtodo que utiliza un parmetro out puede utilizar una variable como tipo de datos devuelto (vea return) pero tambin puede devolver uno o ms objetos a un mtodo de llamada como parmetros out. Este ejemplo utiliza out para devolver tres variables con una nica llamada al mtodo. Observe que el tercer argumento se asigna a null. Esto permite que los mtodos devuelvan valores opcionalmente.

class OutReturnExample { static void Method(out int i, out string s1, out string s2) { i = 44; s1 = "I've been returned"; s2 = null; } static void Main() { int value; string str1, str2; Method(out value, out str1, out str2); // value is now 44 // str1 is now "I've been returned" // str2 is (still) null; } }

MCT: Luis Dueas

Pag 82 de 148

.NET 2 C# .NET

Palabras clave del espacio de nombres


Esta seccin describe las palabras clave y operadores relacionados con el uso de espacios de nombres:

namespace
La palabra clave namespace se utiliza para declarar un mbito. Este mbito permite organizar el cdigo y proporciona una forma de crear tipos globalmente nicos.

namespace name[.name1] ...] { type-declarations }


Parmetros name, name1 Un nombre de espacio de nombres puede ser cualquier identificador vlido. Tambin puede contener puntos. type-declarations Dentro de un espacio de nombres, se pueden declarar uno o varios de los siguientes tipos:

otro espacio de nombres clase (class) interfaz struct enum delegado (delegate)

Comentarios Incluso si no se declara explcitamente, siempre se crea un espacio de nombres predeterminado. Este espacio de nombres sin denominacin, a veces denominado espacio de nombres global, est presente en todos los archivos. Cualquier identificador del espacio de nombres global puede utilizarse tambin en un espacio de nombres declarado. Los espacios de nombres disponen implcitamente de un acceso pblico que no puede modificarse. Un espacio de nombres se puede definir en dos o ms declaraciones. Por ejemplo, en el siguiente ejemplo se definen dos clases como parte del espacio de nombres MyCompany:

// cs_namespace_keyword.cs // compile with: /target:library namespace MyCompany.Proj1 { class MyClass { } } namespace MyCompany.Proj1

MCT: Luis Dueas

Pag 83 de 148

.NET 2 C# .NET
{ class MyClass1 { } }
Ejemplo El siguiente ejemplo muestra cmo realizar una llamada a un mtodo esttico en un espacio de nombres anidado.

// cs_namespace_keyword_2.cs using System; namespace SomeNameSpace { public class MyClass { static void Main() { Nested.NestedNameSpaceClass.SayHello(); } } // a nested namespace namespace Nested { public class NestedNameSpaceClass { public static void SayHello() { Console.WriteLine("Hello"); } } } }
Resultados

Hello

using
La palabra clave using tiene dos usos principales:

Como directiva, cuando se utiliza para crear un alias para un espacio de nombres o para importar tipos definidos en otros espacios de nombres. Vea Directiva using. Como instruccin, cuando define un mbito al final del cual el objeto se destruye. Vea Instruccin using.

using (Directiva)
La directiva using se utiliza para:

MCT: Luis Dueas

Pag 84 de 148

.NET 2 C# .NET

Permitir el uso de tipos en un espacio de nombres, de modo que no sea necesario especificar el uso de un tipo en dicho espacio de nombres. Crear un alias para un espacio de nombres.

La palabra clave using tambin se utiliza para crear instrucciones using que definen cundo se eliminar un objeto.

using namespace; using alias = type|namespace;


Parmetros Alias Smbolo definido por el usuario para representar un espacio de nombres o tipo. alias se puede utilizar para representar el nombre del espacio de nombres. Type El tipo que desea ser representado a travs del alias. namespace El espacio de nombres que desea ser representado a travs del alias. O el espacio de nombres que contiene los tipos que desea utilizar sin tener que especificar el nombre completo. Comentarios El mbito de una directiva using se limita al archivo en el cual aparece. Cree un alias using para que sea ms fcil especificar un identificador de un espacio de nombres o tipo. Cree una directiva using para utilizar los tipos de un espacio de nombres sin tener que especificar el espacio de nombres. Una directiva using no proporciona acceso a ningn espacio de nombres anidado en el espacio de nombres especificado. Los espacios de nombres se dividen en dos categoras: definidos por el usuario y definidos por el sistema. Los espacios de nombres definidos por el usuario se definen en el cdigo fuente. Ejemplo 1 El siguiente ejemplo muestra cmo definir y utilizar un alias using para un espacio de nombres:

using MyAlias = MyCompany.Proj.Nested; // Define an alias to represent a namespace. namespace MyCompany.Proj { public class MyClass { public static void DoNothing() { } } }
Ejemplo 2 El siguiente ejemplo muestra cmo definir una directiva using y un alias using para una clase:

// cs_using_directive2.cs // Using directive. using System;

MCT: Luis Dueas

Pag 85 de 148

.NET 2 C# .NET
// Using alias for a class. using AliasToMyClass = NameSpace1.MyClass; namespace NameSpace1 { public class MyClass { public override string ToString() { return "You are in NameSpace1.MyClass"; } } } namespace NameSpace2 { class MyClass { } } namespace NameSpace3 { // Using directive: using NameSpace1; // Using directive: using NameSpace2; class MainClass { static void Main() { AliasToMyClass somevar = new AliasToMyClass(); Console.WriteLine(somevar); } } }
Resultados

You are in NameSpace1.MyClass

using (Instruccin)
Define un mbito fuera del cual se eliminar un objeto u objetos. Sintaxis

using (Font font1 = new Font("Arial", 10.0f)) { }


Comentarios C#, a travs de Common Language Runtime (CLR) de .NET Framework, libera automticamente la memoria utilizada para almacenar objetos que ya no se requieren. La liberacin de memoria no es determinista; se libera cuando CLR decide realizar la recoleccin de elementos no utilizados. Sin embargo, normalmente es mejor liberar los recursos limitados, como identificadores de archivos y conexiones de red, tan rpido como sea posible. La instruccin using permite al programador especificar cundo los objetos que utilizan recursos deben liberarlos. El objeto proporcionado a la instruccin using debe implementar la interfaz

MCT: Luis Dueas

Pag 86 de 148

.NET 2 C# .NET
IDisposable. Esta interfaz proporciona el mtodo Dispose, que debera liberar los recursos del objeto. Es posible salir de una instruccin using cuando se alcanza el final de la instruccin using o cuando se produce una excepcin y el control abandona el bloque de la instruccin antes de llegar al final. El objeto se puede declarar en la instruccin using, como se mostr anteriormente, a delante de ella, del modo siguiente:

Font font2 = new Font("Arial", 10.0f); using (font2) { // use font2 }


Se pueden utilizar varios objetos con una instruccin using, pero se deben declarar dentro de la instruccin using, como sigue:

using (Font font3 = new Font("Arial", 10.0f), font4 = new Font("Arial", 10.0f)) { // Use font3 and font4. }
Ejemplo El ejemplo siguiente muestra cmo una clase definida por el usuario puede implementar su propio comportamiento Dispose. Observe que su tipo debe heredarse de IDisposable.

using System; class C : IDisposable { public void UseLimitedResource() { Console.WriteLine("Using limited resource..."); } void IDisposable.Dispose() { Console.WriteLine("Disposing limited resource."); } } class Program { static void Main() { using (C c = new C()) { c.UseLimitedResource(); } Console.WriteLine("Now outside using statement."); Console.ReadLine(); } }

MCT: Luis Dueas

Pag 87 de 148

.NET 2 C# .NET

alias externo
A veces puede ser necesario hacer referencia a dos versiones de ensamblados que tienen los mismos nombres completos del tipo, por ejemplo, cuando necesita utilizar dos o ms versiones de un ensamblado en la misma aplicacin. Al utilizar un alias de ensamblado externo, los espacios de nombres de cada ensamblado se pueden ajustar dentro de espacios de nombres de nivel de raz denominados por el alias, lo que permite utilizarlos en el mismo archivo.

Nota

La palabra clave extern tambin se utiliza como un modificador de mtodo, cuando se declara un mtodo escrito en cdigo no administrado. Para hacer referencia a dos ensamblados con los mismos nombres completos del tipo, un alias se debe especificar en la lnea de comandos, del modo siguiente:

/r:GridV1=grid.dll /r:GridV2=grid20.dll
Esto crea los alias externos GridV1 y GridV2. Para utilizar estos alias desde dentro de un programa, haga referencia a ellos mediante la palabra clave extern. Por ejemplo:

extern alias GridV1; extern alias GridV2;


Cada declaracin de alias externo introduce un espacio de nombres de nivel de raz adicional que crea un paralelo (pero no se encuentra dentro de l) al espacio de nombres global. De este modo, es posible hacer referencia a los tipos de cada ensamblado sin ambigedades, mediante su nombre completo, arraigado en el alias de espacio de nombres adecuado En el ejemplo anterior, GridV1::Grid sera el control de cuadrcula de grid.dll y

GridV2::Grid sera el control de cuadrcula de grid20.dll.

MCT: Luis Dueas

Pag 88 de 148

.NET 2 C# .NET

Palabras clave de operadores


Se utiliza para realizar acciones miscelneas como crear objetos, comprobar el tipo en tiempo de ejecucin de un objeto, obtener el tamao de un tipo, y as sucesivamente. Esta seccin presenta las siguientes palabras clave:

o o o o o o o

as is

Convierte un objeto en un tipo compatible. Comprueba el tipo en tiempo de ejecucin de un objeto.

new Operador new Modificador new Restriccin new sizeof typeof true Operador true contrario devuelve false. Literal true false Operador false contrario devuelve false. Literal false stackalloc Representa el valor booleano false. Devuelve el valor booleano true para indicar false y de lo Representa el valor booleano true. Devuelve el valor booleano true para indicar true y de lo Crea objetos. Oculta un miembro heredado. Califica un parmetro de tipo.

Obtiene el tamao de un tipo. Obtiene el objeto System.Type para un tipo.

Asigna un bloque de memoria en la pila.

Las siguientes palabras clave, que se pueden utilizar como operadores e instrucciones, se describen en la seccin Instrucciones:

checked

Especifica un contexto comprobado. Especifica un contexto no comprobado.

unchecked

as
Se utiliza para realizar conversiones entre tipos de referencia compatibles. Por ejemplo: string s = someObject as string;

if (s != null) { // someObject is a string. }


Comentarios El operador as funciona como una conversin de tipos, pero, si existe un error en la conversin, proporciona el valor null en vez de producir una excepcin. Ms formalmente, una expresin de la forma,

expression as type
equivale a,

MCT: Luis Dueas

Pag 89 de 148

.NET 2 C# .NET
expression is type ? (type)expression : (type)null salvo que expression slo se evala una vez.
Debe tenerse en cuenta que el operador as solamente ejecuta conversiones de referencia y conversiones boxing. El operador as no puede realizar otras conversiones, como las definidas por el usuario, que se deben realizar utilizando expresiones de conversin explcitas. Ejemplo

// cs_keyword_as.cs // The as operator. using System; class Class1 { } class Class2 { } class MainClass { static void Main() { object[] objArray = new object[6]; objArray[0] = new Class1(); objArray[1] = new Class2(); objArray[2] = "hello"; objArray[3] = 123; objArray[4] = 123.4; objArray[5] = null; for (int i = 0; i < objArray.Length; ++i) { string s = objArray[i] as string; Console.Write("{0}:", i); if (s != null) { Console.WriteLine("'" + s + "'"); } else { Console.WriteLine("not a string"); } } } }
Resultados

0:not a string 1:not a string 2:'hello' 3:not a string 4:not a string 5:not a string

MCT: Luis Dueas

Pag 90 de 148

.NET 2 C# .NET

is
Comprueba si un objeto es compatible con un tipo determinado. Por ejemplo, se puede determinar si un objeto es compatible con el tipo string de la forma siguiente:

if (obj is string) { }
Comentarios Una expresin is se evala como true si la expresin proporcionada no es NULL y el objeto proporcionado se puede convertir al tipo proporcionado sin producir una excepcin. Para obtener ms informacin, vea 7.6.6 Cast expressions. La palabra clave is tiene como resultado una advertencia en tiempo de compilacin si se sabe que la expresin siempre ser true o siempre ser false, pero normalmente evala la compatibilidad de tipos en tiempo de ejecucin. El operador is no se puede sobrecargar. Observe que el operador is solamente tiene en cuenta las conversiones de referencia, las conversiones boxing y las conversiones unboxing. No se tienen en cuenta otras conversiones, tales como las conversiones definidas por el usuario. Ejemplo

// cs_keyword_is.cs // The is operator. using System; class Class1 { } class Class2 { } class IsTest { static void Test(object o) { Class1 a; Class2 b; if (o is Class1) { Console.WriteLine("o is Class1"); a = (Class1)o; // Do something with "a." } else if (o is Class2) { Console.WriteLine("o is Class2"); b = (Class2)o; // Do something with "b." } else { Console.WriteLine("o is neither Class1 nor Class2."); } }

MCT: Luis Dueas

Pag 91 de 148

.NET 2 C# .NET
static void Main() { Class1 c1 = new Class1(); Class2 c2 = new Class2(); Test(c1); Test(c2); Test("a string"); } }
Resultados

o is Class1 o is Class2 o is neither Class1 nor Class2.

new
En C#, la palabra clave new se puede utilizar como operador, modificador o restriccin. new (Operador) Se utiliza para crear objetos e invocar constructores. new (Modificador) Se utiliza para ocultar un miembro heredado de un miembro de clase base. new (Restriccin) Se utiliza para restringir tipos que se podran utilizar como argumentos para un parmetro de tipo en una declaracin genrica.

new (Operador)
Se utiliza para crear objetos e invocar constructores. Por ejemplo:

Class1 o = new Class1();


El operador new tambin se utiliza para invocar el constructor predeterminado de los tipos de valor. Por ejemplo:

int i = new int();


En la instruccin anterior se inicializa i con el valor 0, que es el predeterminado para el tipo int. Esa instruccin tiene el mismo efecto que:

int i = 0;
Recuerde que es un error declarar un constructor predeterminado para un tipo struct, ya que todos los tipos de valores poseen implcitamente un constructor pblico predeterminado. Es posible declarar constructores parametrizados en un tipo struct para establecer sus valores iniciales, pero slo es necesario si se requieren valores distintos del predeterminado. Los objetos de tipo valor, tales como las estructuras, se crean en la pila, mientras que los objetos de tipo referencia, tales como las clases, se crean en el montn. Ambos tipos de objetos se destruyen automticamente, pero los objetos basados en tipos de valor se destruyen cuando salen del mbito, mientras que los objetos basados en tipos de referencia se destruyen en un momento

MCT: Luis Dueas

Pag 92 de 148

.NET 2 C# .NET
no especificado despus de quitar la ltima referencia a ellos. En los tipos de referencia que consumen ciertos recursos, como grandes cantidades de memoria, identificadores de archivo o conexiones de red, a veces es conveniente emplear la finalizacin determinista para asegurarse de que el objeto se destruir lo antes posible. El operador new no se puede sobrecargar. Si el operador new no puede asignar memoria, producir la excepcin OutOfMemoryException. Ejemplo En el siguiente ejemplo, se crean e inicializan, mediante el operador new, un objeto struct y un objeto class y, a continuacin, se les asignan valores. Se muestran los valores predeterminados y asignados.

// cs_operator_new.cs // The new operator. using System; struct SampleStruct { public int x; public int y; public SampleStruct(int x, int y) { this.x = x; this.y = y; } } class SampleClass { public string name; public int id; public SampleClass() {} public SampleClass(int id, string name) { this.id = id; this.name = name; } } class MainClass { static void Main() { // Create objects using default constructors: SampleStruct Location1 = new SampleStruct(); SampleClass Employee1 = new SampleClass(); // Display values: Console.WriteLine("Default values:"); Console.WriteLine(" Struct members: {0}, {1}", Location1.x, Location1.y); Console.WriteLine(" Class members: {0}, {1}", Employee1.name, Employee1.id);

MCT: Luis Dueas

Pag 93 de 148

.NET 2 C# .NET
// Create objects using parameterized constructors: SampleStruct Location2 = new SampleStruct(10, 20); SampleClass Employee2 = new SampleClass(1234, "John Martin Smith"); // Display values: Console.WriteLine("Assigned values:"); Console.WriteLine(" Struct members: {0}, {1}", Location2.x, Location2.y); Console.WriteLine(" Class members: {0}, {1}", Employee2.name, Employee2.id); } }
Resultados

Default values: Struct members: 0, 0 Class members: , 0 Assigned values: Struct members: 10, 20 Class members: John Martin Smith, 1234

new (Modificador)
Cuando se utiliza como modificador, la palabra clave new oculta explcitamente un miembro heredado de una clase base. Ocultar un miembro heredado significa que la versin derivada del miembro reemplaza la versin de la clase base. Aunque se permite ocultar miembros sin utilizar el modificador new, se genera una advertencia. El uso de new para ocultar explcitamente un miembro suprime esta advertencia y documenta el hecho de que la versin derivada est concebida como un reemplazo. Para ocultar un miembro heredado, declrelo en la clase derivada con el mismo nombre y modifquelo con el modificador new. Por ejemplo:

public class BaseC { public int x; public void Invoke() {} } public class DerivedC : BaseC { new public void Invoke() {} } En este ejemplo, DerivedC.Invoke oculta BaseC.Invoke. El campo x no se ve afectado
porque no lo oculta un nombre similar. La ocultacin de nombres por medio de la herencia toma una de las siguientes formas:

Constante, campo, propiedad o tipo introducido en una clase o estructura que oculta todos los miembros de la clase base con el mismo nombre. Mtodo introducido en una clase o estructura que oculta propiedades, campos y tipos, con el mismo nombre, en la clase base. Tambin oculta todos los mtodos de la clase base con la misma firma.

MCT: Luis Dueas

Pag 94 de 148

.NET 2 C# .NET

Indizador introducido en una clase o estructura que oculta todos los indizadores de la clase base con la misma firma. Es un error utilizar new y override en el mismo miembro, ya que los dos modificadores tienen significados mutuamente exclusivos. Al utilizar new, se crea un nuevo miembro con el mismo nombre y el miembro original queda oculto, mientras que override ampla la implementacin de un miembro heredado. Si se utiliza el modificador new en una declaracin que no oculta un miembro heredado, se genera una advertencia. Ejemplo En este ejemplo, una clase base, BaseC, y una clase derivada, DerivedC, utilizan el mismo nombre de campo x, lo que produce la ocultacin del valor del campo heredado. El ejemplo muestra el uso del modificador new. Tambin muestra cmo obtener acceso a los miembros ocultos de la clase base mediante sus nombres completos.

// cs_modifier_new.cs // The new modifier. using System; public class BaseC { public static int x = 55; public static int y = 22; } public class DerivedC : BaseC { // Hide field 'x' new public static int x = 100; static void Main() { // Display the new value of x: Console.WriteLine(x); // Display the hidden value of x: Console.WriteLine(BaseC.x); // Display the unhidden member y: Console.WriteLine(y); } }
Resultados

100 55 22
En este ejemplo, una clase anidada oculta una clase con el mismo nombre en la clase base. El ejemplo muestra el uso del modificador new para eliminar el mensaje de advertencia, as como el acceso a los miembros ocultos de la clase mediante sus nombres completos.

// cs_modifer_new_nested.cs // Using the new modifier with nested types. using System; public class BaseC { public class NestedC

MCT: Luis Dueas

Pag 95 de 148

.NET 2 C# .NET
{ public int x = 200; public int y; } } public class DerivedC : BaseC { // Nested type hiding the base type members. new public class NestedC { public int x = 100; public int y; public int z; } static void Main() { // Creating an object from the overlapping class: NestedC c1 = new NestedC(); // Creating an object from the hidden class: BaseC.NestedC c2 = new BaseC.NestedC(); Console.WriteLine(c1.x); Console.WriteLine(c2.x); } }
Resultados

100 200
Comentarios Si quita el modificador new, el programa seguir compilndose y ejecutndose, pero aparecer la siguiente advertencia:

The keyword new is required MyDerivedC because it hides inherited member MyBaseC
Tambin puede utilizar el modificador new para modificar un tipo anidado si ste est ocultando otro tipo, como se muestra en el ejemplo siguiente.

Restriccin new
La restriccin new especifica que, en una declaracin de clase genrica, cualquier argumento de tipo debe tener un constructor pblico sin parmetros. Aplique esta restriccin a un parmetro de tipo cuando una clase genrica cree nuevas instancias del tipo, como se muestra en el ejemplo siguiente:

class ItemFactory<T> where T : new() { public T GetNewItem() { return new T(); } }


Cuando se utiliza la restriccin new() con otras restricciones, se debe especificar en ltimo lugar:

using System; public class ItemFactory<T> where T : IComparable, new() { }

MCT: Luis Dueas

Pag 96 de 148

.NET 2 C# .NET

sizeof
Se utiliza para obtener el tamao en bytes para un tipo de valor. Por ejemplo, el tamao del tipo int se puede recuperar de la manera siguiente:

int intSize = sizeof(int);


Comentarios El operador sizeof slo se puede aplicar a tipos de valor, no a tipos de referencia.

Nota

A partir de la versin 2.0 de C# en adelante, la aplicacin de sizeof a los tipos predefinidos, ya no requiere la utilizacin del modo unsafe. El operador sizeof no puede sobrecargarse. Los valores devueltos por el operador sizeof son del tipo int. La tabla siguiente muestra los valores constantes que representan los tamaos de ciertos tipos predefinidos.

Expresin sizeof(sbyte) sizeof(byte) sizeof(short) sizeof(ushort) sizeof(int) sizeof(uint) sizeof(long) sizeof(ulong) sizeof(char) sizeof(float) sizeof(double) sizeof(bool)

Resultado 1 1 2 2 4 4 8 8 2 (Unicode) 4 8 1

Para todos los otros tipos, entre ellos las estructuras, el operador sizeof se puede utilizar slo en bloques de cdigo no seguros. Aunque se puede utilizar el mtodo SizeOf, el valor devuelto por este mtodo no siempre es igual al valor devuelto por sizeof. Marshal.SizeOf devuelve el tamao despus de calcular las referencias del tipo, mientras que sizeof devuelve el tamao cuando ste ha sido asignado por Common Language Runtime, incluido cualquier valor de relleno. Ejemplo

// cs_operator_sizeof.cs // compile with: /unsafe using System; class MainClass { unsafe static void Main()

MCT: Luis Dueas

Pag 97 de 148

.NET 2 C# .NET
{ Console.WriteLine("The size of short is {0}.", sizeof(short)); Console.WriteLine("The size of int is {0}.", sizeof(int)); Console.WriteLine("The size of long is {0}.", sizeof(long)); } }
Resultados

The size of short is 2. The size of int is 4. The size of long is 8.

typeof
Obtenga el objeto System.Type para un tipo. Una expresin typeof se presenta de la siguiente forma:

System.Type type = typeof(int);


Comentarios Para obtener el tipo de una expresin en tiempo de ejecucin, puede utilizar el mtodo GetType de .NET Framework de la manera siguiente.

int i = 0; System.Type type = i.GetType();


El operador typeof tambin se puede utilizar en tipos de genricos abiertos. Los tipos con ms de un parmetro de tipo deben tener el nmero adecuado de comas en la especificacin. El operador typeof no se puede sobrecargar. Ejemplo

// cs_operator_typeof.cs using System; using System.Reflection; public class SampleClass { public int sampleMember; public void SampleMethod() {} static void Main() { Type t = typeof(SampleClass); // Alternatively, you could use // SampleClass obj = new SampleClass(); // Type t = obj.GetType(); Console.WriteLine("Methods:"); MethodInfo[] methodInfo = t.GetMethods(); foreach (MethodInfo mInfo in methodInfo) Console.WriteLine(mInfo.ToString()); Console.WriteLine("Members:"); MemberInfo[] memberInfo = t.GetMembers(); foreach (MemberInfo mInfo in memberInfo) Console.WriteLine(mInfo.ToString()); } }

MCT: Luis Dueas

Pag 98 de 148

.NET 2 C# .NET
Resultados

Methods: Void SampleMethod() System.Type GetType() System.String ToString() Boolean Equals(System.Object) Int32 GetHashCode() Members: Void SampleMethod() System.Type GetType() System.String ToString() Boolean Equals(System.Object) Int32 GetHashCode() Void .ctor() Int32 sampleMember
En este ejemplo se utiliza el mtodo GetType para determinar el tipo utilizado para contener el resultado de un clculo numrico. Esto depende de los requisitos de almacenamiento del nmero resultante.

// cs_operator_typeof2.cs using System; class GetTypeTest { static void Main() { int radius = 3; Console.WriteLine("Area = {0}", radius * radius * Math.PI); Console.WriteLine("The type is {0}", (radius * radius * Math.PI).GetType() ); } }
Resultados

Area = 28.2743338823081 The type is System.Double

true
Se utiliza como un operador sobrecargado o como un literal: true (Operador) true (Literal)

true (Operador)
Devuelve el valor booleano true para indicar que es verdadero; devuelve false cuando lo define un tipo definido por el usuario. Esto resulta til para tipos que representan valores true, false y null (ni true ni false), como los utilizados en bases de datos. Esos tipos se pueden utilizar en las expresiones de control de las instrucciones if, do, while y for, as como en expresiones condicionales. Si un tipo define el operador true, tambin debe definir el operador false.

MCT: Luis Dueas

Pag 99 de 148

.NET 2 C# .NET
Un tipo no puede sobrecargar directamente los operadores lgicos condicionales (&& y ||), pero al sobrecargar los operadores lgicos regulares y los operadores true y false se puede lograr un efecto equivalente.

true (Literal)
Representa el valor booleano true. Ejemplo

// cs_keyword_true.cs using System; class TestClass { static void Main() { bool a = true; Console.WriteLine( a ? "yes" : "no" ); } }
Resultados

yes

false
Se utiliza como un operador sobrecargado o como un literal:

false (Operador) false (Literal)

false (Operador)
Devuelve el valor booleano true para indicar false y devuelve false de lo contrario. Esto resulta til para tipos que representan valores true, false y null (ni true ni false), como los utilizados en bases de datos. Esos tipos se pueden utilizar en las expresiones de control de las instrucciones if, do, while y for, as como en expresiones condicionales. Si un tipo define el operador false, tambin debe definir el operador true. Un tipo no puede sobrecargar directamente los operadores lgicos condicionales && y ||, pero al sobrecargar los operadores lgicos regulares y los operadores true y false se puede lograr un efecto equivalente.

false (Literal)
Representa el valor booleano false. Ejemplo

MCT: Luis Dueas

Pag 100 de 148

.NET 2 C# .NET
// cs_keyword_false.cs using System; class TestClass { static void Main() { bool a = false; Console.WriteLine( a ? "yes" : "no" ); } }
Resultados

no

stackalloc
Permite asignar un bloque de memoria en la pila.

type * ptr = stackalloc type [ expr ];


Parmetros Type Tipo no administrado. ptr Nombre de puntero. expr Expresin entera. Comentarios Un bloque de memoria de tamao suficiente para contener elementos expr de tipo type se reserva en la pila y no en el montn; la direccin del bloque se almacena en el puntero ptr. Esta memoria no est sometida a reciclaje y, por lo tanto, no necesita fijarse (por medio de fixed). El perodo de duracin del bloque de memoria se limita al perodo de duracin del mtodo en el que est definido (no hay forma de liberar la memoria antes de la devolucin del mtodo). El operador stackalloc slo es vlido en inicializadores de variables locales. Dado que intervienen los tipos de puntero, stackalloc requiere el contexto unsafe. stackalloc es similar a _alloca de la biblioteca en tiempo de ejecucin de C. Seguridad El cdigo no seguro es inherentemente menos seguro que las alternativas seguras. Sin embargo, el uso de stackalloc habilita automticamente las caractersticas de deteccin de saturacin del bfer en Common Language Runtime (CLR). Si se detecta una saturacin del bfer, el proceso se finaliza tan rpidamente como sea posible para reducir la oportunidad de que se ejecute cdigo malintencionado.

MCT: Luis Dueas

Pag 101 de 148

.NET 2 C# .NET
Ejemplo

// cs_keyword_stackalloc.cs // compile with: /unsafe using System; class Test { static unsafe void Main() { int* fib = stackalloc int[100]; int* p = fib; *p++ = *p++ = 1; for (int i = 2; i < 100; ++i, ++p) { *p = p[-1] + p[-2]; } for (int i = 0; i < 10; ++i) { Console.WriteLine(fib[i]); } } }
Resultados

1 1 2 3 5 8 13 21 34 55

MCT: Luis Dueas

Pag 102 de 148

.NET 2 C# .NET

Palabras clave para conversiones


Esta seccin describe palabras clave utilizadas para conversiones de tipos:

explicit
La palabra clave explicit declara un operador de conversin de tipos definido por el usuario que se debe invocar con una conversin de tipos. Por ejemplo, este operador convierte una clase denominada Fahrenheit en una clase denominada Celsius:

// Must be defined inside a class called Farenheit: public static explicit operator Celsius(Farenheit f) { return new Celsius((5.0f/9.0f)*(f.degrees-32)); }
El operador de conversin se puede invocar as:

Farenheit f = new Farenheit(100.0f); Celsius c = (Celsius)f;


Comentarios El operador de conversin convierte un tipo de origen en un tipo de destino. El tipo de origen proporciona el operador de conversin. A diferencia de la conversin implcita, los operadores de conversin explcita deben invocarse mediante una conversin de tipo (cast). Si una operacin de conversin puede producir excepciones o prdida de informacin, debe marcarse como explicit. De esta forma, se evita que el compilador realice la conversin automticamente y se produzcan posibles consecuencias no deseadas. Si no se utiliza esta conversin explcita, se produce el error de compilacin Error del compilador CS0266. Ejemplo El ejemplo siguiente proporciona una clase Fahrenheit y una clase Celsius, cada una de las cuales proporciona un operador de conversin explcito a la otra clase.

// cs_keyword_explicit_temp.cs using System; class Celsius { public Celsius(float temp) { degrees = temp; } public static explicit operator Fahrenheit(Celsius c) { return new Fahrenheit((9.0f / 5.0f) * c.degrees + 32); } public float Degrees { get { return degrees;

MCT: Luis Dueas

Pag 103 de 148

.NET 2 C# .NET
} } private float degrees; } class Fahrenheit { public Fahrenheit(float temp) { degrees = temp; } public static explicit operator Celsius(Fahrenheit f) { return new Celsius((5.0f / 9.0f) * (f.degrees - 32)); } public float Degrees { get { return degrees; } } private float degrees; } class MainClass { static void Main() { Fahrenheit f = new Fahrenheit(100.0f); Console.Write("{0} fahrenheit", f.Degrees); Celsius c = (Celsius)f; Console.Write(" = {0} celsius", c.Degrees); Fahrenheit f2 = (Fahrenheit)c; Console.WriteLine(" = {0} fahrenheit", f2.Degrees); } }
Resultados

100 fahrenheit = 37.77778 celsius = 100 fahrenheit El siguiente ejemplo define una estructura, Digit, que representa un nico dgito decimal. Se define un operador para conversiones de byte a Digit, pero como no todos los bytes se pueden convertir en Digit, la conversin es explcita. // cs_keyword_explicit_2.cs using System; struct Digit { byte value; public Digit(byte value) { if (value > 9) {

MCT: Luis Dueas

Pag 104 de 148

.NET 2 C# .NET
throw new ArgumentException(); } this.value = value; } // Define explicit byte-to-Digit conversion operator: public static explicit operator Digit(byte b) { Digit d = new Digit(b); Console.WriteLine("conversion occurred"); return d; } } class MainClass { static void Main() { try { byte b = 3; Digit d = (Digit)b; // explicit conversion } catch (Exception e) { Console.WriteLine("{0} Exception caught.", e); } } }
Resultados

conversion occurred

implicit
La palabra clave implicit se utiliza para declarar un operador de conversin de tipo implcito definido por el usuario.

static implicit operator target_type { source_type identifier }


Parmetros target_type Tipo de referencia. source_type Tipo de referencia. identifier Algo. Comentarios Si se eliminan las conversiones de tipo explcitas innecesarias y se utilizan conversiones implcitas, la legibilidad del cdigo mejora. No obstante, como las conversiones implcitas pueden tener lugar

MCT: Luis Dueas

Pag 105 de 148

.NET 2 C# .NET
sin que el programador las especifique, debe tenerse cuidado para no obtener resultados no deseados. En general, los operadores de conversin implcita nunca deberan producir excepciones ni prdida de informacin, de modo que puedan utilizarse de forma segura sin intervencin del programador. Si un operador de conversin no cumple esos criterios, debera marcarse como explicit.

class MyType { public static implicit operator int(MyType m) { // code to convert from MyType to int } }
Los operadores de conversin implcita pueden invocarse de forma implcita, sin necesidad de especificarlos mediante conversiones de tipo explcitas (cast) en el cdigo fuente.

MyType x; // implicitly call MyType's MyType-to-int conversion operator int i = x;

operator
La palabra clave operator se utiliza para declarar un operador en una declaracin de clase o estructura. Una declaracin de operador puede presentar una de las siguientes cuatro formas:

public static public static operand2 ) public static public static


Parmetros result-type

result-type operator unary-operator ( op-type operand ) result-type operator binary-operator ( op-type operand, op-type2 implicit operator conv-type-out ( conv-type-in operand ) explicit operator conv-type-out ( conv-type-in operand )

Tipo del resultado del operador. unary-operator Uno de los siguientes: + op-type Tipo del primer (o nico) parmetro. operand Nombre del primer (o nico) parmetro. binary-operator Uno de los siguientes: + op-type2 Tipo del segundo parmetro. operand2 Nombre del segundo parmetro. * / % & | ^ << >> == != > < >= <= ! ~ ++ true false

MCT: Luis Dueas

Pag 106 de 148

.NET 2 C# .NET
conv-type-out Tipo de destino de un operador de conversin de tipos. conv-type-in Tipo de entrada de un operador de conversin de tipos. Comentarios Las dos primeras formas declaran operadores definidos por el usuario que sobrecargan operadores integrados. Tenga en cuenta que no todos los operadores integrados pueden sobrecargarse (vea Operadores sobrecargables). Por lo menos uno de los tipos op-type u op-type2 debe ser el tipo envolvente (es decir, el tipo del que el operador es un miembro). De este modo, por ejemplo, se evita tener que redefinir el operador de adicin de enteros. Las dos ltimas formas declaran operadores de conversin. Uno de los tipos conv-type-in o conv-type-out debe ser el tipo envolvente (es decir, un operador de conversin slo puede convertir de su tipo envolvente a algn otro tipo o viceversa). Los operadores slo pueden tomar parmetros de valor, no parmetros ref o out. Cualquier declaracin de operador puede estar precedida por una lista opcional de Atributos. Ejemplo A continuacin, se muestra una clase muy simplificada para nmeros racionales. Sobrecarga los operadores + y * para implementar la adicin y multiplicacin de nmeros fraccionarios, y tambin proporciona un operador que convierte fracciones en nmeros reales de tipo double.

// cs_keyword_operator.cs using System; class Fraction { int num, den; public Fraction(int num, int den) { this.num = num; this.den = den; } // overload operator + public static Fraction operator +(Fraction a, Fraction b) { return new Fraction(a.num * b.den + b.num * a.den, a.den * b.den); } // overload operator * public static Fraction operator *(Fraction a, Fraction b) { return new Fraction(a.num * b.num, a.den * b.den); } // define operator double public static implicit operator double(Fraction f) { return (double)f.num / f.den; } }

MCT: Luis Dueas

Pag 107 de 148

.NET 2 C# .NET
class Test { static void Main() { Fraction a = new Fraction(1, Fraction b = new Fraction(3, Fraction c = new Fraction(2, Console.WriteLine((double)(a } }
Resultados

2); 7); 3); * b + c));

0.880952380952381

Palabras clave de acceso


Esta seccin presenta las siguientes palabras clave de acceso:

base Obtiene acceso a los miembros de la clase base.

this Hace referencia a la instancia actual de la clase.

base
La palabra clave base se utiliza para obtener acceso a los miembros de la clase base desde una clase derivada:

Realice una llamada a un mtodo de la clase base reemplazado por otro mtodo. Especifique a qu constructor de la clase base se debe llamar para crear instancias de la clase derivada.

El acceso a una clase base slo se permite en un constructor, en un mtodo de instancia o en un descriptor de acceso a una propiedad de instancia. Es incorrecto utilizar la palabra clave base desde dentro de un mtodo esttico. Ejemplo En este ejemplo, tanto la clase base, Person, como la clase derivada, Employee, poseen un mtodo denominado Getinfo. Mediante la palabra clave base, se puede realizar una llamada al mtodo Getinfo de la clase base desde la clase derivada.

// keywords_base.cs // Accessing base class members using System; public class Person { protected string ssn = "444-55-6666"; protected string name = "John L. Malgraine";

MCT: Luis Dueas

Pag 108 de 148

.NET 2 C# .NET
public virtual void GetInfo() { Console.WriteLine("Name: {0}", name); Console.WriteLine("SSN: {0}", ssn); } } class Employee : Person { public string id = "ABC567EFG"; public override void GetInfo() { // Calling the base class GetInfo method: base.GetInfo(); Console.WriteLine("Employee ID: {0}", id); } } class TestClass { static void Main() { Employee E = new Employee(); E.GetInfo(); } }
Este ejemplo muestra cmo especificar el constructor de la clase base al que se realiza la llamada cuando se crean instancias de una clase derivada.

// keywords_base2.cs using System; public class BaseClass { int num; public BaseClass() { Console.WriteLine("in BaseClass()"); } public BaseClass(int i) { num = i; Console.WriteLine("in BaseClass(int i)"); } public int GetNum() { return num; } } public class DerivedClass : BaseClass { // This constructor will call BaseClass.BaseClass() public DerivedClass() : base() { } // This constructor will call BaseClass.BaseClass(int i)

MCT: Luis Dueas

Pag 109 de 148

.NET 2 C# .NET
public DerivedClass(int i) : base(i) { } static void Main() { DerivedClass md = new DerivedClass(); DerivedClass md1 = new DerivedClass(1); } }
Resultados

Name: John L. Malgraine SSN: 444-55-6666 Employee ID: ABC567EFG


Resultados

in BaseClass() in BaseClass(int i)

this
La palabra clave this hace referencia a la instancia actual de la clase. A continuacin, se indican algunos usos comunes de this:

Obtener acceso a miembros con el fin de evitar ambigedades con nombres similares, por ejemplo:

public Employee(string name, string alias) { this.name = name; this.alias = alias; }


Pasar un objeto como parmetro a otros mtodos, por ejemplo, para:

CalcTax(this);
Declarar indizadores, por ejemplo:

public int this [int param] { get { return array[param]; } set { array[param] = value; } }
Debido a que las funciones miembro estticas existen en el nivel de clase y no como parte de un objeto, no tienen un puntero this. Es un error hacer referencia a this en un mtodo esttico. Ejemplo En este ejemplo, this se utiliza para calificar los miembros de la clase Employee, name y

alias, que presentan ambigedad con nombres similares. Tambin se utiliza para pasar un objeto al mtodo CalcTax, el cual pertenece a otra clase.

MCT: Luis Dueas

Pag 110 de 148

.NET 2 C# .NET
// keywords_this.cs // this example using System; class Employee { private string name; private string alias; private decimal salary = 3000.00m; // Constructor: public Employee(string name, string alias) { // Use this to qualify the fields, name and alias: this.name = name; this.alias = alias; } // Printing method: public void printEmployee() { Console.WriteLine("Name: {0}\nAlias: {1}", name, alias); // Passing the object to the CalcTax method by using this: Console.WriteLine("Taxes: {0:C}", Tax.CalcTax(this)); } public decimal Salary { get { return salary; } } } class Tax { public static decimal CalcTax(Employee E) { return 0.08m * E.Salary; } } class MainClass { static void Main() { // Create objects: Employee E1 = new Employee("John M. Trainer", "jtrainer"); // Display results: E1.printEmployee(); } }
Resultados

Name: John M. Trainer Alias: jtrainer Taxes: $240.00

MCT: Luis Dueas

Pag 111 de 148

.NET 2 C# .NET

Palabras clave de literales


C# dispone de las siguientes palabras clave para literales:

null true false default

null
La palabra clave null es un literal que representa una referencia null, es decir, una referencia que no apunta a ningn objeto. null es el valor predeterminado de las variables de tipo de referencia. C# 2.0 introduce tipos que aceptan valores NULL, que son tipos de datos que se pueden establecer en un valor indefinido.

default
Palabra clave default. La palabra clave default se puede utilizar en la instruccin switch o en cdigo genrico:

Instruccin switch: Especifica la etiqueta predeterminada. Cdigo genrico: Especifica el valor predeterminado del parmetro de tipo. ste ser null para los tipos de referencia y cero para los tipos de valor.

Palabras clave contextuales


Las palabras clave contextuales se utilizan para proporcionar un significado concreto en el cdigo, sin embargo no son palabras reservadas de C#. En esta seccin se describen las siguientes palabras clave contextuales: get Define un mtodo de descriptor de acceso para una propiedad o un indizador. Define clases parciales, estructuras e interfaces a lo largo de la misma unidad de

partial

compilacin. set Define un mtodo de descriptor de acceso para una propiedad o un indizador. Agrega restricciones a una declaracin genrica. Se utiliza en un bloque de iteradores para devolver un valor al objeto de enumerador o

where yield

tambin para sealar el final de iteracin. value Se utiliza para establecer los descriptores de acceso y para agregar o quitar los

controladores de eventos.

MCT: Luis Dueas

Pag 112 de 148

.NET 2 C# .NET

get
Define un mtodo de descriptor de acceso en una propiedad o indizador que recupera el valor de la propiedad o el elemento del indizador. ste es un ejemplo de un descriptor de acceso get para una propiedad denominada Seconds:

class TimePeriod { private double _seconds; public double Seconds { get { return _seconds; } set { _seconds = value; } } }

partial
Las definiciones de tipo parcial permiten dividir la definicin de una clase, estructura o interfaz en varios archivos.

[modifiers] partial type


Parmetros modifier (opcional) Modificadores opcionales, entre los que se incluyen:


type

abstract new override static virtual extern uno de los cuatro modificadores de acceso

Uno de:

clase (class) struct interfaz

MCT: Luis Dueas

Pag 113 de 148

.NET 2 C# .NET
Comentarios Dividir una clase, estructura o tipo de interfaz en varios archivos puede ser til al trabajar con proyectos grandes o cdigo generado automticamente.

set
Define un mtodo de descriptor de acceso en una propiedad o indizador que estableci el valor de la propiedad o el elemento del indizador. Vea Propiedades e Indizadores para obtener ms informacin. ste es un ejemplo de un descriptor de acceso set para una propiedad denominada Seconds:

class TimePeriod { private double _seconds; public double Seconds { get { return _seconds; } set { _seconds = value; } } }

value
El parmetro implcito value se usa para configurar descriptores de acceso y para agregar o eliminar controladores de eventos.

where
La clusula where se utiliza para especificar restricciones sobre los tipos que se pueden utilizar como argumentos para un parmetro de tipo definido en una declaracin genrica. Por ejemplo, puede declarar una clase genrica, MyGenericClass, de modo que el parmetro de tipo T implemente la interfaz IComparable<T>:

public class MyGenericClass<T> where T:IComparable { }


Adems de las restricciones de interfaz, una clusula where puede incluir una restriccin de clase base, que establece que un tipo debe tener la clase especificada como clase base (o ser la propia clase) para poder utilizarlo como argumento de tipo para ese tipo genrico. Si se utiliza una restriccin semejante, debe aparecer antes que cualquier otra restriccin sobre ese parmetro de tipo.

MCT: Luis Dueas

Pag 114 de 148

.NET 2 C# .NET
// cs_where.cs // compile with: /target:library using System; class MyClassy<T, U> where T : class where U : struct { }
La clusula where tambin puede incluir una restriccin de constructor. Es posible crear una instancia de un parmetro de tipo utilizando el operador new; sin embargo, para ello el parmetro de tipo debe estar restringido por la restriccin de constructor, new(). La restriccin new() permite que el compilador sepa que cualquier argumento de tipo que se proporcione debe tener un constructor sin parmetros accesible, o predeterminado. Por ejemplo:

// cs_where_2.cs // compile with: /target:library using System; public class MyGenericClass <T> where T: IComparable, new() { // The following line is not possible without new() constraint: T item = new T(); }
La restriccin new() aparece en ltimo lugar en la clusula where. Con varios parmetros de tipo, utilice una clusula where para cada parmetro de tipo, por ejemplo:

// cs_where_3.cs // compile with: /target:library using System; using System.Collections; interface MyI { } class Dictionary<TKey,TVal> where TKey: IComparable, IEnumerable where TVal: MyI { public void Add(TKey key, TVal val) { } }
Tambin puede adjuntar restricciones a parmetros de tipo de mtodos genricos, como el siguiente:

public bool MyMethod<T>(T t) where T : IMyInterface { }


Observe que la sintaxis para describir las restricciones de parmetros de tipo en delegados es igual que la sintaxis de mtodos.

delegate T MyDelegate<T>() where T : new()

MCT: Luis Dueas

Pag 115 de 148

.NET 2 C# .NET

yield
Se utiliza en un bloque iterator para proporcionar un valor al objeto enumerador o sealar el fin de la iteracin. Presenta una de las siguientes formas:

yield return expression; yield break;


Parmetros expression Si se evala y devuelve un valor al objeto enumerador, expression se debe poder convertir al tipo yield del iterador. Comentarios La instruccin yield slo puede aparecer dentro de un bloque iterator que podra utilizarse como cuerpo de un mtodo, operador o descriptor de acceso. El cuerpo de dicho mtodo, operador o descriptor de acceso se controla mediante las siguientes restricciones:

No se permiten bloques unsafe. Los parmetros del mtodo, operador o descriptor de acceso no pueden ser ref ni out.

Una instruccin yield no puede aparecer en un mtodo annimo. Cuando se utiliza con expression, una instruccin yield return no puede aparecer en un bloque catch ni en un bloque try que tengan una o ms clusulas catch. Ejemplo En el siguiente ejemplo, la instruccin yield se utiliza dentro de un bloque de iteradores, que es el mtodo Power(int number, int power). Cuando se invoca al mtodo Power, este devuelve un objeto enumerable que contiene las potencias de un nmero. Observe que el tipo de valor devuelto del mtodo Power es IEnumerable, un tipo de interfaz de iteradores.

// yield-example.cs using System; using System.Collections; public class List { public static IEnumerable Power(int number, int exponent) { int counter = 0; int result = 1; while (counter++ < exponent) { result = result * number; yield return result; } } static void Main() { // Display powers of 2 up to the exponent 8: foreach (int i in Power(2, 8)) { Console.Write("{0} ", i); } } }
Resultados

2 4 8 16 32 64 128 256

MCT: Luis Dueas

Pag 116 de 148

.NET 2 C# .NET

Operadores de C#
C# proporciona un amplio conjunto de operadores, que son smbolos que especifican las operaciones que se deben realizar en una expresin. C# dispone de los operadores aritmticos y lgicos habituales, y de una gran variedad de otros operadores, como se muestra en la siguiente tabla. Generalmente se permiten en las enumeraciones las operaciones de tipos integrales como ==, !=, <, >, <=, >=, binary +, binary -, ^, &, |, ~, ++, -- y sizeof(). Adems, el usuario puede sobrecargar muchos de los operadores, es decir, cambiar su significado al aplicarlos a un tipo definido por el usuario.

Categoras

Operadores

Aritmticos Lgicos (booleanos y bit a bit) Concatenacin de cadenas Incremento y decremento Desplazamiento Relacionales Asignacin Acceso a miembros Indizacin Conversin de tipos explcita Condicional Concatenacin y eliminacin de delegados Creacin de objetos Informacin de tipos Control de excepciones de desbordamiento Direccionamiento indirecto y direccin Desbordamiento aritmtico

+ - * / % & | ^ ! ~ && || true false + ++ -<< >> == != < > <= >= = += -= *= /= %= &= |= ^= <<= >>= ?? . [] () ?: + new as is sizeof typeof checked unchecked * -> [] &

Los operadores aritmticos (+, -, *, /) pueden producir resultados fuera del intervalo de valores posibles para el tipo numrico implicado. Aunque para encontrar informacin detallada, debe consultar la seccin acerca del operador especfico; en general, podemos decir:

El desbordamiento aritmtico de enteros produce una excepcin de desbordamiento (OverflowException) o bien elimina los bits ms significativos del resultado. La divisin de enteros por cero siempre produce una excepcin DivideByZeroException.

El desbordamiento aritmtico o la divisin por cero en punto flotante no producen una excepcin, ya que los tipos de punto flotante se basan en el estndar IEEE 754, que proporciona una representacin para los valores infinito y NaN (Not a Number, no es un nmero).

MCT: Luis Dueas

Pag 117 de 148

.NET 2 C# .NET

El desbordamiento aritmtico de valores de tipo decimal siempre produce una excepcin OverflowException. La divisin de decimales por cero siempre produce una excepcin DivideByZeroException. Cuando se produce un desbordamiento de enteros, lo que ocurre depende del contexto de la ejecucin, el cual puede ser checked o unchecked. En un contexto checked (comprobado), se produce una excepcin OverflowException. En un contexto unchecked (no comprobado), los bits ms significativos del resultado no se tienen en cuenta y la ejecucin contina. De esta forma, C# permite elegir entre atender o desatender el desbordamiento. Adems de los operadores aritmticos, las conversiones entre tipos integrales tambin pueden producir desbordamiento; por ejemplo, al convertir un tipo long en un tipo int, y estn sometidas al tipo de ejecucin checked o unchecked. Sin embargo, los operadores bit a bit y los operadores de desplazamiento nunca producen desbordamiento.

Operador []
Los corchetes ([]) se utilizan para matrices, indizadores y atributos. Tambin se pueden utilizar con punteros. Comentarios Un tipo de matriz es un tipo seguido de []:

int[] fib; // fib is of type int[], "array of int" fib = new int[100]; // create a 100-element int array
Para obtener acceso a un elemento de la matriz, el ndice del elemento deseado se encierra entre corchetes:

fib[0] = fib[1] = 1; for( int i=2; i<100; ++i ) fib[i] = fib[i-1] + fib[i-2];
Se produce una excepcin si el ndice de la matriz est fuera del intervalo declarado. El operador de indizacin de la matriz no se puede sobrecargar; no obstante, los tipos pueden definir indizadores y propiedades que aceptan uno o varios parmetros. Los parmetros de un indizador van entre corchetes, como los ndices de una matriz, pero se pueden declarar de cualquier tipo, a diferencia de los ndices de una matriz, que slo pueden ser de tipo integral. Por ejemplo, .NET Framework define un tipo Hashtable que asocia claves y valores de tipo arbitrario:

Collections.Hashtable h = new Collections.Hashtable(); h["a"] = 123; // note: using a string as the index
Los corchetes tambin se utilizan para especificar Atributos.

[attribute(AllowMultiple=true)] public class Attr { }


Puede utilizar los corchetes para indizar fuera de un puntero:

unsafe fixed ( int* p = fib ) // p points to fib from earlier example { p[0] = p[1] = 1; for( int i=2; i<100; ++i ) p[i] = p[i-1] + p[i-2]; }
No obstante, tenga en cuenta que no se realiza una comprobacin de los lmites del ndice.

MCT: Luis Dueas

Pag 118 de 148

.NET 2 C# .NET

Operador ()
Adems de su uso para especificar el orden de las operaciones en una expresin, los parntesis se utilizan para especificar conversiones de tipo explcitas:

double x = 1234.7; int a; a = (int)x; // cast double to int


Comentarios Una conversin de tipos invoca explcitamente el operador de conversin de un tipo a otro; se producir un error en la conversin si no se ha definido ese operador. El operador () no se puede sobrecargar. Una expresin de conversin de tipos puede llevar a una sintaxis ambigua. Por ejemplo, la expresin (x)y puede interpretarse como una expresin de conversin de tipos (una conversin del tipo y al tipo x) o como una expresin de suma combinada con una expresin entre parntesis, que calcula el valor de x y.

Operador
El operador de punto (.) se utiliza para el acceso a miembros. El operador de punto especifica un miembro de un tipo o espacio de nombres. Por ejemplo, el operador de punto se utiliza para tener acceso a mtodos especficos dentro de las bibliotecas de clases de .NET Framework:

// The class Console in namespace System: System.Console.WriteLine("hello");


Comentarios Por ejemplo, considere la siguiente clase:

class Simple { public int a; public void b() { } } Simple s = new Simple(); La variable s tiene dos miembros, a y b; para tener acceso a ellos, use el operador de punto: s.a = 6; // assign to field a; s.b(); // invoke member function b;
El punto tambin se utiliza para formar nombres completos, que son nombres que especifican el espacio de nombres o la interfaz, por ejemplo, a la que pertenecen.

// The class Console in namespace System: System.Console.WriteLine("hello");


La directiva using hace que la calificacin de nombres sea opcional en algunos casos:

using System; // ... System.Console.WriteLine("hello"); Console.WriteLine("hello"); // same thing


Sin embargo, un identificador ambiguo debe calificarse:

using System;

MCT: Luis Dueas

Pag 119 de 148

.NET 2 C# .NET
// A namespace containing another Console class: using OtherSystem; // ... // Must qualify Console: System.Console.WriteLine( "hello" );

Operador ::
Operador calificador de alias de espacio de nombres. El calificador de alias de espacio de nombres (::) se utiliza para buscar identificadores. Siempre aparece entre dos identificadores, como en este ejemplo:

global::System.Console.WriteLine("Hello World");
Comentarios El calificador de alias de espacio de nombres puede ser global. ste invoca una bsqueda del espacio de nombres global, en lugar de un espacio de nombres con alias.

Operador +
El operador + puede funcionar como operador unario o binario. Comentarios Los operadores unarios + se encuentran predefinidos para todos los tipos numricos. El resultado de una operacin unaria + aplicada a un tipo numrico es simplemente el valor del operando. Los operadores + binarios se encuentran predefinidos para los tipos numricos y de cadena. Para tipos numricos, + calcula la suma de sus dos operandos. Cuando al menos uno de los operandos es de tipo string, + concatena las representaciones de tipo string de los operandos. Los tipos delegados tambin proporcionan un operador binario +, el cual realiza la concatenacin de delegados. Los tipos definidos por el usuario pueden sobrecargar los operadores unario y binario +. Las operaciones en tipos integrales se suelen permitir en enumeraciones. Ejemplo

// cs_operator_plus.cs using System; class MainClass { static void Main() { Console.WriteLine(+5); // unary plus Console.WriteLine(5 + 5); // addition Console.WriteLine(5 + .5); // addition Console.WriteLine("5" + "5"); // string concatenation Console.WriteLine(5.0 + "5"); // string concatenation

MCT: Luis Dueas

Pag 120 de 148

.NET 2 C# .NET
// note automatic conversion from double to string } }
Resultados

5 10 5.5 55 55

Operador El operador - puede funcionar como operador unario o binario. Comentarios Los operadores unarios - se encuentran predefinidos para todos los tipos numricos. El resultado de una operacin unaria - aplicada a un tipo numrico es la negacin numrica del operando. Los operadores binarios - estn predefinidos para todos los tipos numricos y de enumeracin de modo que restan el segundo operando del primero. Los tipos delegados tambin proporcionan un operador binario -, el cual realiza la eliminacin de delegados. Los tipos definidos por el usuario pueden sobrecargar los operadores unario y binario -. Para obtener ms informacin, vea operador. Ejemplo

// cs_operator_minus.cs using System; class MainClass { static void Main() { int a = 5; Console.WriteLine(-a); Console.WriteLine(a - 1); Console.WriteLine(a - .5); } }
Resultados

-5 4 4.5

Operador *
Operador de multiplicacin (*) que calcula el producto de sus operandos. Adems, operador de eliminacin de referencias que permite leer y escribir en un puntero. Comentarios Todos los tipos numricos poseen operadores de multiplicacin predefinidos. El operador * tambin se utiliza para declarar los tipos de puntero y para eliminar referencias de los punteros. Este operador slo se puede utilizar en contextos no seguros, indicados por el uso de

MCT: Luis Dueas

Pag 121 de 148

.NET 2 C# .NET
la palabra clave unsafe, y que requieren la opcin del compilador /unsafe. El operador de eliminacin de referencias tambin se conoce como el operador de direccionamiento indirecto. Los tipos definidos por el usuario pueden sobrecargar el operador binario *. Cuando se sobrecarga un operador binario, el operador de asignacin correspondiente, si existe, tambin se sobrecarga de modo implcito. Ejemplo

// cs_operator_mult.cs using System; class MainClass { static void Main() { Console.WriteLine(5 * 2); Console.WriteLine(-.5 * .2); Console.WriteLine(-.5m * .2m); // decimal type } }
Resultados

10 -0.1 -0.10 // cs_operator_ptr.cs // compile with: /unsafe public class MainClass { unsafe static void Main() { int i = 5; int* j = &i; System.Console.WriteLine(*j); } }
Resultados

Operador /
El operador de divisin (/) permite dividir el primer operando por el segundo. Todos los tipos numricos poseen operadores de divisin predefinidos. Comentarios Los tipos definidos por el usuario pueden sobrecargar el operador / (vea operador). Si se sobrecarga el operador /, se sobrecarga implcitamente el operador /=. Ejemplo

// cs_operator_division.cs using System; class MainClass

MCT: Luis Dueas

Pag 122 de 148

.NET 2 C# .NET
{ static void Main() { Console.WriteLine(-5/2); Console.WriteLine(-5.0/2); } }
Resultados

-2 -2.5

Operador %
El operador de mdulo (%) calcula el resto de dividir su primer operando por el segundo. Todos los tipos numricos poseen operadores de mdulo predefinidos. Comentarios Los tipos definidos por el usuario pueden sobrecargar el operador % (vea operador). Cuando se sobrecarga un operador binario, el operador correspondiente de asignacin (si existe) tambin se sobrecarga de modo implcito. Ejemplo

// cs_operator_modulus.cs using System; class MainClass { static void Main() { Console.WriteLine(5 % 2); // int Console.WriteLine(-5 % 2); // int Console.WriteLine(5.0 % 2.2); // double Console.WriteLine(5.0m % 2.2m); // decimal Console.WriteLine(-5.2 % 2.0); // double } }
Resultados

1 -1 0.6 0.6 -1.2

Operador &
El operador & puede funcionar como operador unario o binario. Comentarios El operador & unario devuelve la direccin de memoria de su operando (requiere un contexto unsafe). Los operadores & binarios estn predefinidos para los tipos integrales y bool. Para tipos integrales, & calcula la operacin AND bit a bit lgica de sus operandos. Para operandos de tipo

MCT: Luis Dueas

Pag 123 de 148

.NET 2 C# .NET
bool, & calcula la operacin lgica AND de sus operandos; es decir, el resultado es true si, y slo si ambos operandos son true. El operador & evala ambos operadores sin tener en cuenta el valor del primero. Por ejemplo:

int i = 0; if (false & ++i == 1) { // i is incremented, but the conditional // expression evaluates to false, so // this block does not execute. }
Los tipos definidos por el usuario pueden sobrecargar el operador binario &. Las operaciones en tipos integrales se suelen permitir en enumeraciones. Cuando se sobrecarga un operador binario, el operador de asignacin correspondiente, si existe, tambin se sobrecarga de modo implcito. Ejemplo

// cs_operator_ampersand.cs using System; class MainClass { static void Main() { Console.WriteLine(true & false); // logical and Console.WriteLine(true & true); // logical and Console.WriteLine("0x{0:x}", 0xf8 & 0x3f); // bitwise and } }
Resultados

False True 0x38

Operador |
Los operadores binarios | estn predefinidos para tipos integrales y bool. Para los tipos integrales, | calcula la operacin OR bit a bit de sus operandos. Para operandos de tipo bool, | calcula la operacin lgica OR de sus operandos; es decir, el resultado es false si, y slo si, ambos operandos son false. Comentarios Los tipos definidos por el usuario pueden sobrecargar el operador | (vea operador). Ejemplo

// cs_operator_OR.cs using System; class MainClass { static void Main() { Console.WriteLine(true | false);

MCT: Luis Dueas

Pag 124 de 148

.NET 2 C# .NET
// logical or Console.WriteLine(false | false); // logical or Console.WriteLine("0x{0:x}", 0xf8 | 0x3f); // bitwise or } }
Resultados

True False 0xff

Operador ^
Los operadores binarios ^ estn predefinidos para tipos integrales y bool. Para los tipos integrales, ^ calcula la operacin OR exclusiva bit a bit de sus operandos. Para los operandos bool, ^ calcula la operacin OR exclusiva lgica de sus operandos; es decir, el resultado es true si, y slo si, exactamente uno de sus operandos es true. Comentarios Los tipos definidos por el usuario pueden sobrecargar el operador ^ (vea operador). Las operaciones en tipos integrales se suelen permitir en enumeraciones. Ejemplo

// cs_operator_bitwise_OR.cs using System; class MainClass { static void Main() { Console.WriteLine(true ^ false); // logical exclusive-or Console.WriteLine(false ^ false); // logical exclusive-or // Bitwise exclusive-or: Console.WriteLine("0x{0:x}", 0xf8 ^ 0x3f); } }
Resultados

True False 0xc7

Operador !
El operador lgico de negacin (!) es un operador unario que niega su operando. Est definido para el tipo bool y devuelve true si, y slo si, su operando es false. Comentarios Los tipos definidos por el usuario pueden sobrecargar el operador ! (vea operador). Ejemplo

// cs_operator_negation.cs using System; class MainClass

MCT: Luis Dueas

Pag 125 de 148

.NET 2 C# .NET
{ static void Main() { Console.WriteLine(!true); Console.WriteLine(!false); } }
Resultados

False True

Operador ~
El operador ~ realiza una operacin de complemento bit a bit en su operando, lo que tiene el efecto de invertir cada bit. Los operadores de complemento bit a bit estn predefinidos para int, uint, long y ulong. Comentarios Los tipos definidos por el usuario pueden sobrecargar el operador ~. Las operaciones en tipos integrales se suelen permitir en enumeraciones. Ejemplo

// cs_operator_bitwise_compl.cs using System; class MainClass { static void Main() { int[] values = { 0, 0x111, 0xfffff, 0x8888, 0x22000022}; foreach (int v in values) { Console.WriteLine("~0x{0:x8} = 0x{1:x8}", v, ~v); } } }
Resultados

~0x00000000 ~0x00000111 ~0x000fffff ~0x00008888 ~0x22000022

= = = = =

0xffffffff 0xfffffeee 0xfff00000 0xffff7777 0xddffffdd

Operador =
El operador de asignacin (=) almacena el valor del operando situado a su derecha en la ubicacin de almacenamiento, propiedad o indizador indicados por el operando situado a su izquierda y devuelve el valor como resultado. Los operandos deben ser del mismo tipo (o el operando de la derecha se debe poder convertir implcitamente al tipo del operando de la izquierda).

MCT: Luis Dueas

Pag 126 de 148

.NET 2 C# .NET
Comentarios El operador de asignacin no se puede sobrecargar. Ejemplo

// cs_operator_assignment.cs using System; class MainClass { static void Main() { double x; int i; i = 5; // int to int assignment x = i; // implicit conversion from int to double i = (int)x; // needs cast Console.WriteLine("i is {0}, x is {1}", i, x); object obj = i; Console.WriteLine("boxed value = {0}, type is {1}", obj, obj.GetType()); i = (int)obj; Console.WriteLine("unboxed: {0}", i); } }
Resultados

i is 5, x is 5 boxed value = 5, type is System.Int32 unboxed: 5

Operador <
Todos los tipos numricos y de enumeracin definen un operador relacional "menor que" (<) que devuelve true si el primer operando es menor que el segundo y false en caso contrario. Comentarios Los tipos definidos por el usuario pueden sobrecargar el operador < (vea operador). Si se sobrecarga <, tambin se debe sobrecargar >. Cuando se sobrecarga un operador binario, el operador correspondiente de asignacin (si existe) tambin se sobrecarga de modo implcito. Ejemplo

// cs_operator_less_than.cs using System; class MainClass { static void Main() { Console.WriteLine(1 < 1.1); Console.WriteLine(1.1 < 1.1); } }
Resultados

True False

MCT: Luis Dueas

Pag 127 de 148

.NET 2 C# .NET

Operador >
Todos los tipos numricos y de enumeracin definen un operador relacional "mayor que" (>) que devuelve true si el primer operando es mayor que el segundo y false en caso contrario. Comentarios Los tipos definidos por el usuario pueden sobrecargar el operador > (vea operador). Si se sobrecarga >, tambin se debe sobrecargar <. Cuando se sobrecarga un operador binario, el operador correspondiente de asignacin (si existe) tambin se sobrecarga de modo implcito. Ejemplo

// cs_operator_greater_than.cs using System; class MainClass { static void Main() { Console.WriteLine(1.1 > 1); Console.WriteLine(1.1 > 1.1); } }
Resultados

True False

Operador ?:
El operador condicional (?:) devuelve uno de dos valores segn el valor de una expresin booleana. El operador condicional tiene el formato

condition ? first_expression : second_expression;


Comentarios Si la condicin es true, se evala la primera expresin y se convierte en el resultado; si es false, se evala la segunda expresin y se convierte en el resultado. Slo se evala una de las dos expresiones. Los clculos que, en cualquier otro caso, podran requerir un bloque de decisin if-else se pueden expresar ms concisa y elegantemente mediante el operador condicional. Por ejemplo, para evitar una divisin por cero en el clculo de la funcin sin, podra escribirse

if(x != 0.0) s = Math.Sin(x)/x; else s = 1.0;


o bien, con el operador condicional,

s = x != 0.0 ? Math.Sin(x)/x : 1.0;


El operador condicional es asociativo por la derecha, de modo que una expresin de la forma:

a ? b : c ?d : e
se evala como

a ? b : (c ? d : e)
y no como

MCT: Luis Dueas

Pag 128 de 148

.NET 2 C# .NET
(a ? b : c) ? d : e
El operador condicional no se puede sobrecargar. Ejemplo

// cs_operator_conditional.cs using System; class MainClass { static double sinc(double x) { return x != 0.0 ? Math.Sin(x)/x : 1.0; } static void Main() { Console.WriteLine(sinc(0.2)); Console.WriteLine(sinc(0.1)); Console.WriteLine(sinc(0.0)); } }
Resultados

0.993346653975306 0.998334166468282 1

Operador ++
El operador de incremento (++) incrementa su operando en 1. El operador de incremento puede aparecer antes o despus de su operando: Comentarios La primera forma es una operacin de incremento prefijo. El resultado de la operacin es el valor del operando despus de haber sido incrementado. La segunda forma es una operacin de incremento postfijo. El resultado de la operacin es el valor del operando antes de haber sido incrementado. Los tipos numricos y de enumeracin poseen operadores de incremento predefinidos. Los tipos definidos por el usuario pueden sobrecargar el operador ++ Las operaciones en tipos integrales se suelen permitir en enumeraciones. Ejemplo

// cs_operator_increment.cs using System; class MainClass { static void Main() { double x; x = 1.5;

MCT: Luis Dueas

Pag 129 de 148

.NET 2 C# .NET
Console.WriteLine(++x); x = 1.5; Console.WriteLine(x++); Console.WriteLine(x); } }
Resultados

2.5 1.5 2.5

Operador -El operador de disminucin (--) disminuye su operando en 1. El operador de disminucin puede aparecer antes o despus de su operando: --variable y variable--. La primera forma es una operacin de decremento prefijo. El resultado de la operacin es el valor del operando "despus" de haber sido decrementado. La segunda forma es una operacin de decremento postfijo. El resultado de la operacin es el valor del operando "antes" de haber sido decrementado. Comentarios Los tipos numricos y de enumeracin poseen operadores de decremento predefinidos. Los tipos definidos por el usuario pueden sobrecargar el operador -- (vea operador). Las operaciones en tipos integrales se suelen permitir en enumeraciones. Ejemplo

// cs_operator_decrement.cs using System; class MainClass { static void Main() { double x; x = 1.5; Console.WriteLine(--x); x = 1.5; Console.WriteLine(x--); Console.WriteLine(x); } }
Resultados

0.5 1.5 0.5

MCT: Luis Dueas

Pag 130 de 148

.NET 2 C# .NET

Operador &&
El operador AND condicional (&&) realiza una operacin lgica AND de sus operandos de tipo bool, pero slo evala su segundo operando si es necesario. Comentarios La operacin

x && y
se corresponde con la operacin

x & y
excepto que si x es false, y no se evala (ya que el resultado de la operacin AND ser false independientemente del valor de y ). Esto se conoce como evaluacin "cortocircuitada". El operador AND condicional no se puede sobrecargar, pero las sobrecargas de los operadores lgicos normales y los operadores true y false tambin se consideran, con ciertas restricciones, sobrecargas de los operadores lgicos condicionales. Ejemplo En el siguiente ejemplo, observe que la expresin que utiliza && slo evala el primer operando.

// cs_operator_logical_and.cs using System; class MainClass { static bool Method1() { Console.WriteLine("Method1 called"); return false; } static bool Method2() { Console.WriteLine("Method2 called"); return true; } static void Main() { Console.WriteLine("regular AND:"); Console.WriteLine("result is {0}", Method1() & Method2()); Console.WriteLine("short-circuit AND:"); Console.WriteLine("result is {0}", Method1() && Method2()); } }
Resultados

regular AND: Method1 called Method2 called result is False shortcircuit AND: Method1 called result is False

MCT: Luis Dueas

Pag 131 de 148

.NET 2 C# .NET

Operador ||
El operador OR condicional (||) realiza una operacin lgica OR de sus operandos de tipo bool, pero slo evala su segundo operando si es necesario. Comentarios La operacin

x || y
se corresponde con la operacin

x | y
salvo que si x es true, y no se evala (ya que el resultado de la operacin OR ser true independientemente del valor de y). Esto se conoce como evaluacin "cortocircuitada". El operador OR condicional no se puede sobrecargar, pero las sobrecargas de los operadores lgicos normales y los operadores true y false se consideran tambin, con ciertas restricciones, sobrecargas de los operadores lgicos condicionales. Ejemplo En el siguiente ejemplo, observe que la expresin que utiliza || slo evala el primer operando.

// cs_operator_short_circuit_OR.cs using System; class MainClass { static bool Method1() { Console.WriteLine("Method1 called"); return true; } static bool Method2() { Console.WriteLine("Method2 called"); return false; } static void Main() { Console.WriteLine("regular OR:"); Console.WriteLine("result is {0}", Method1() | Method2()); Console.WriteLine("short-circuit OR:"); Console.WriteLine("result is {0}", Method1() || Method2()); } }
Resultados

regular OR: Method1 called Method2 called result is True short-circuit OR: Method1 called result is True

MCT: Luis Dueas

Pag 132 de 148

.NET 2 C# .NET

Operador <<
El operador de desplazamiento a la izquierda (<<) desplaza su primer operando a la izquierda el nmero de bits especificado por su segundo operando. El tipo del segundo operando debe ser int. Comentarios Si el primer operando es int o uint (cantidad de 32 bits), los cinco bits de orden inferior del segundo operando proporcionan el valor de desplazamiento. Si el primer operando es long o ulong (cantidad de 64 bits), los seis bits de orden inferior del segundo operando proporcionan el valor de desplazamiento. Los bits de orden superior del primer operando se descartan y los bits vacos de orden inferior se rellenan con ceros. Las operaciones de desplazamiento nunca producen desbordamientos. Los tipos definidos por el usuario pueden sobrecargar el operador << (vea operator (Referencia de C#)); el tipo del primer operando debe ser el tipo definido por el usuario, mientras que el tipo del segundo operando debe ser int. Cuando se sobrecarga un operador binario, el operador correspondiente de asignacin, si existe, tambin se sobrecarga de modo implcito. Ejemplo

// cs_operator_left_shift.cs using System; class MainClass { static void Main() { int i = 1; long lg = 1; Console.WriteLine("0x{0:x}", i << 1); Console.WriteLine("0x{0:x}", i << 33); Console.WriteLine("0x{0:x}", lg << 33); } }
Resultados

0x2 0x2 0x200000000

Operador >>
El operador de desplazamiento a la derecha (>>) desplaza su primer operando a la derecha el nmero de bits especificado por su segundo operando. Comentarios Si el primer operando es int o uint (cantidad de 32 bits), los cinco bits de orden inferior del segundo operando proporcionan el valor de desplazamiento (segundo operando & 0x1f). Si el primer operando es long o ulong (cantidad de 64 bits), los seis bits de orden inferior del segundo operando proporcionan el valor de desplazamiento (segundo operando & 0x3f).

MCT: Luis Dueas

Pag 133 de 148

.NET 2 C# .NET
Si el primer operando es un tipo int o long, el desplazamiento a la derecha es un desplazamiento aritmtico (los bits vacos de orden superior toman el bit de signo). Si el primer operando es del tipo uint o ulong, el desplazamiento a la derecha es un desplazamiento lgico (los bits de orden superior se rellenan con ceros). Los tipos definidos por el usuario pueden sobrecargar el operador >>; el tipo del primer operando debe ser el tipo definido por el usuario, mientras que el tipo del segundo operando debe ser int. Para obtener ms informacin, vea operator (Referencia de C#)). Cuando se sobrecarga un operador binario, el operador de asignacin correspondiente, si existe, tambin se sobrecarga de modo implcito. Ejemplo

// cs_operator_right_shift.cs using System; class MainClass { static void Main() { int i = -1000; Console.WriteLine(i >> 3); } }
Resultados

-125

Operador ==
Para los tipos de valores predefinidos, el operador de igualdad (==) devuelve true si los valores de sus operandos son iguales y false en caso contrario. Para los tipos de referencia, excepto string, == devuelve true si sus dos operandos se refieren al mismo objeto. Para el tipo string, == compara los valores de las cadenas. Comentarios Los tipos definidos por el usuario pueden sobrecargar el operador == (vea operator (Referencia de C#)). Tambin pueden hacerlo los tipos de referencia definidos por el usuario, aunque, de forma predeterminada, == se comporta como se ha descrito anteriormente tanto para los tipos de referencia predefinidos como para los definidos por el usuario. Si se sobrecarga ==, tambin se debe sobrecargar !=. Las operaciones en tipos integrales se suelen permitir en enumeraciones. Ejemplo

// cs_operator_equality.cs using System; class MainClass { static void Main() { // Numeric equality: True Console.WriteLine((2 + 2) == 4); // Reference equality: different objects,

MCT: Luis Dueas

Pag 134 de 148

.NET 2 C# .NET
// same boxed value: False. object s = 1; object t = 1; Console.WriteLine(s == t); // Define some strings: string a = "hello"; string b = String.Copy(a); string c = "hello"; // Compare string values of a constant and an instance: True Console.WriteLine(a == b); // Compare string references; // a is a constant but b is an instance: False. Console.WriteLine((object)a == (object)b); // Compare string references, both constants // have the same value, so string interning // points to same reference: True. Console.WriteLine((object)a == (object)c); } }
Resultados

True False True False True

Operador !=
El operador de desigualdad (!=) devuelve false si sus dos operandos son iguales; en caso contrario, devuelve true. Los operadores de desigualdad estn predefinidos para todos los tipos, incluidos string y object. Los tipos definidos por el usuario pueden sobrecargar el operador != Comentarios Para los tipos de valores predefinidos, el operador de desigualdad (!=) devuelve true si los valores de sus operandos son diferentes, y false en caso contrario. Para los tipos de referencia, excepto string, != devuelve true si sus dos operandos se refieren a objetos diferentes. Para el tipo string, != compara los valores de las cadenas. Los tipos definidos por el usuario pueden sobrecargar el operador !=. Tambin pueden hacerlo los tipos de referencia definidos por el usuario, aunque, de forma predeterminada, != se comporta como se ha descrito anteriormente tanto para los tipos de referencia predefinidos como para los definidos por el usuario. Si se sobrecarga !=, tambin se debe sobrecargar ==. Las operaciones en tipos integrales se suelen permitir en enumeraciones. Ejemplo

// cs_operator_inequality.cs using System; class MainClass { static void Main() { // Numeric inequality: Console.WriteLine((2 + 2) != 4); // Reference equality: two objects, same boxed value

MCT: Luis Dueas

Pag 135 de 148

.NET 2 C# .NET
object s = 1; object t = 1; Console.WriteLine(s != t); // String equality: same string value, same string objects string a = "hello"; string b = "hello"; // compare string values Console.WriteLine(a != b); // compare string references Console.WriteLine((object)a != (object)b); } }
Resultados

False True False False

Operador <=
Todos los tipos numricos y de enumeracin definen un operador relacional "menor o igual que" (<=) que devuelve true si el primer operando es menor o igual que el segundo y devuelve false en caso contrario. Comentarios Los tipos definidos por el usuario pueden sobrecargar el operador <=. Si se sobrecarga <=, tambin se debe sobrecargar >=. Las operaciones en tipos integrales se suelen permitir en enumeraciones. Ejemplo

// cs_operator_less_than_or_equal.cs using System; class MainClass { static void Main() { Console.WriteLine(1 <= 1.1); Console.WriteLine(1.1 <= 1.1); } }
Resultados

True True

Operador >=
Todos los tipos numricos y de enumeracin definen un operador relacional "mayor o igual que" (>=) que devuelve true si el primer operando es mayor o igual que el segundo, y devuelve false en caso contrario. Comentarios

MCT: Luis Dueas

Pag 136 de 148

.NET 2 C# .NET
Los tipos definidos por el usuario pueden sobrecargar el operador >= Para obtener ms informacin, vea operador. Si se sobrecarga >=, tambin se debe sobrecargar <=. Las operaciones en tipos integrales se suelen permitir en enumeraciones. Ejemplo

// cs_operator_greater_than_or_equal.cs using System; class MainClass { static void Main() { Console.WriteLine(1.1 >= 1); Console.WriteLine(1.1 >= 1.1); } }
Resultados

True True

Operador +=
El operador de asignacin y suma. Comentarios Una expresin que utiliza el operador de asignacin +=, por ejemplo

x += y
equivale a

x = x + y salvo que x slo se evala una vez. El significado del operador + depende de los tipos de x e y
(suma para operandos numricos, concatenacin para operandos de tipo cadena, etc.). El operador += no se puede sobrecargar directamente, pero los tipos definidos por el usuario s pueden sobrecargar el operador +. Ejemplo

// cs_operator_addition_assignment.cs using System; class MainClass { static void Main() { int a = 5; a += 6; Console.WriteLine(a); string s = "Micro"; s += "soft"; Console.WriteLine(s); } }

MCT: Luis Dueas

Pag 137 de 148

.NET 2 C# .NET
Resultados

11 Microsoft

Operador -=
El operador de asignacin y resta. Comentarios Una expresin que utiliza el operador de asignacin -=, por ejemplo

x -= y
equivale a

x = x - y salvo que x slo se evala una vez. El significado del operador - depende de los tipos de x e y
(resta para operandos numricos, eliminacin delegada para operandos delegados, etc.). El operador -= no se puede sobrecargar directamente, pero los tipos definidos por el usuario s pueden sobrecargar el operador - (vea operador). Ejemplo

// cs_operator_subtraction_assignment.cs using System; class MainClass { static void Main() { int a = 5; a -= 6; Console.WriteLine(a); } }
Resultado

-1

Operador *=
El operador de asignacin y multiplicacin binario. Comentarios Una expresin que utiliza el operador de asignacin *=, por ejemplo

x *= y
equivale a

x = x * y salvo que x slo se evala una vez. El operador * est predefinido con la multiplicacin para tipos
numricos.

MCT: Luis Dueas

Pag 138 de 148

.NET 2 C# .NET
El operador *= no se puede sobrecargar directamente, pero los tipos definidos por el usuario s pueden sobrecargar el operador *. Ejemplo

// cs_operator_multiplication_assignment.cs using System; class MainClass { static void Main() { int a = 5; a *= 6; Console.WriteLine(a); } }
Resultados

30

Operador /=
El operador de asignacin y divisin. Comentarios Una expresin que utiliza el operador de asignacin /=, por ejemplo

x /= y
equivale a

x = x / y salvo que x slo se evala una vez. El operador / est predefinido con la divisin para tipos
numricos. El operador /= no se puede sobrecargar directamente, pero los tipos definidos por el usuario s pueden sobrecargar el operador /. En todos los operadores de asignacin compuesta, al sobrecargar el operador binario implcitamente se sobrecarga la asignacin compuesta equivalente. Ejemplo

// cs_operator_division_assignment.cs using System; class MainClass { static void Main() { int a = 5; a /= 6; Console.WriteLine(a); double b = 5; b /= 6; Console.WriteLine(b); }

MCT: Luis Dueas

Pag 139 de 148

.NET 2 C# .NET
}
Resultados

0 0.833333333333333

Operador %=
El operador de asignacin de mdulo. Comentarios Una expresin que utiliza el operador de asignacin %=, por ejemplo

x %= y
equivale a

x = x % y salvo que x slo se evala una vez. El operador % est predefinido en tipos numricos para
calcular el resto de la divisin. El operador %= no se puede sobrecargar directamente, pero los tipos definidos por el usuario s pueden sobrecargar el operador %. Ejemplo

// cs_operator_modulus_assignment.cs using System; class MainClass { static void Main() { int a = 5; a %= 3; Console.WriteLine(a); } }
Resultados

Operador &=
El operador de asignacin y AND. Comentarios Una expresin que utiliza el operador de asignacin &=, por ejemplo

x &= y
equivale a

x = x & y

MCT: Luis Dueas

Pag 140 de 148

.NET 2 C# .NET
salvo que x slo se evala una vez. El operador & realiza una operacin AND bit a bit lgica sobre operandos integrales y una operacin AND lgica sobre operandos bool. El operador &= no se puede sobrecargar directamente, pero los tipos definidos por el usuario s pueden sobrecargar el operador & binario. Ejemplo

// cs_operator_and_assignment.cs using System; class MainClass { static void Main() { int a = 0x0c; a &= 0x06; Console.WriteLine("0x{0:x8}", a); bool b = true; b &= false; Console.WriteLine(b); } }
Resultados

0x00000004 False

Operador |=
El operador de asignacin OR. Comentarios Una expresin que utiliza el operador de asignacin |=, por ejemplo

x |= y
equivale a

x = x | y salvo que x slo se evala una vez. El operador | realiza una operacin lgica OR bit a bit sobre
operandos integrales y una operacin lgica OR sobre operandos de tipo bool. El operador |= no se puede sobrecargar directamente, pero los tipos definidos por el usuario s pueden sobrecargar el operador |. Ejemplo

// cs_operator_or_assignment.cs using System; class MainClass { static void Main() { int a = 0x0c; a |= 0x06;

MCT: Luis Dueas

Pag 141 de 148

.NET 2 C# .NET
Console.WriteLine("0x{0:x8}", a); bool b = true; b |= false; Console.WriteLine(b); } }
Resultados

0x0000000e True

Operador ^=
El operador de asignacin y OR exclusivo. Comentarios Una expresin de la forma

x ^= y
se evala como

x = x ^ y salvo que x slo se evala una vez. El operador ^ realiza una operacin OR exclusiva bit a bit
sobre operandos integrales y una operacin OR exclusiva lgica sobre operandos de tipo bool. El operador ^= no se puede sobrecargar directamente, pero los tipos definidos por el usuario s pueden sobrecargar el operador !. Ejemplo

// cs_operator_xor_assignment.cs using System; class MainClass { static void Main() { int a = 0x0c; a ^= 0x06; Console.WriteLine("0x{0:x8}", a); bool b = true; b ^= false; Console.WriteLine(b); } }
Resultados

0x0000000a True

MCT: Luis Dueas

Pag 142 de 148

.NET 2 C# .NET

Operador <<=
El operador de asignacin y desplazamiento a la izquierda. Comentarios Una expresin de la forma

x <<= y
se evala como

x = x << y salvo que x slo se evala una vez. El operador << desplaza x a la izquierda el nmero de bits especificado por y.
El operador <<= no se puede sobrecargar directamente, pero los tipos definidos por el usuario s pueden sobrecargar el operador << (vea operador). Ejemplo

// cs_operator_left_shift_assignment.cs using System; class MainClass { static void Main() { int a = 1000; a <<= 4; Console.WriteLine(a); } }
Resultados

16000

Operador >>=
El operador de asignacin y desplazamiento a la derecha. Comentarios Una expresin de la forma

x >>= y
se evala como

x = x >> y salvo que x slo se evala una vez. El operador >> desplaza x a la derecha el nmero de bits especificado por y.
El operador >>= no se puede sobrecargar directamente, pero los tipos definidos por el usuario s pueden sobrecargar el operador >>. Ejemplo

// cs_operator_right_shift_assignment.cs

MCT: Luis Dueas

Pag 143 de 148

.NET 2 C# .NET
using System; class MainClass { static void Main() { int a = 1000; a >>= 4; Console.WriteLine(a); } }
Resultados

62

Operador ->
El operador -> combina la eliminacin de referencias de un puntero y el acceso a un miembro. Comentarios Una expresin de la forma

x->y
(donde x es un puntero de tipo T* e y es un miembro de T) equivale a

(*x).y
El operador -> slo se puede utilizar en cdigo no administrado. El operador -> no se puede sobrecargar. Ejemplo

// cs_operator_dereferencing.cs // compile with: /unsafe using System; struct Point { public int x, y; } class MainClass { unsafe static void Main() { Point pt = new Point(); Point* pp = &pt; pp->x = 123; pp->y = 456; Console.WriteLine ( "{0} {1}", pt.x, pt.y ); } }
Resultados

123 456

MCT: Luis Dueas

Pag 144 de 148

.NET 2 C# .NET

Operador ??
El operador ?? devuelve el operando izquierdo si es not-null, en los dems casos devuelve el operando derecho. Comentarios Un tipo que acepta valores NULL puede contener un valor o puede ser indefinido. El operador ?? define el valor predeterminado para devolver cuando un tipo que acepta valores NULL se asigna a un tipo que no acepta valores NULL. Si intenta asignar un tipo que acepta valores NULL a un tipo que no acepta valores NULL sin utilizar el operador ??, se generar un error en tiempo de compilacin. Si utiliza una conversin de tipos, y el tipo que acepta valores NULL se encuentra en ese momento indefinido, se producir una excepcin InvalidOperationException. Ejemplo

// nullable_type_operator.cs using System; class MainClass { static int? GetNullableInt() { return null; } static string GetStringValue() { return null; } static void Main() { // ?? operator example. int? x = null; // y = x, unless x is null, in which case y = -1. int y = x ?? -1; // Assign i to return value of method, unless // return value is null, in which case assign // default value of int to i. int i = GetNullableInt() ?? default(int); string s = GetStringValue(); // ?? also works with reference types. // Display contents of s, unless s is null, // in which case display "Unspecified". Console.WriteLine(s ?? "Unspecified"); } }

MCT: Luis Dueas

Pag 145 de 148

.NET 2 C# .NET

Terminologa de C#
Campo [field] Miembro de datos de una clase o estructura a la que se tiene acceso directamente. Clase [class] Tipo de datos que describe un objeto. Las clases contienen datos y mtodos que actan en los datos. Clase base [base class] Clase heredada por otra clase 'derivada'. Clase derivada [derived class] Clase que utiliza la herencia para obtener, aumentar o modificar el comportamiento y los datos de otra clase 'base'. Constructor [constructor] Mtodo especial de una clase o estructura que inicializa objetos de ese tipo. Delegado [delegate] Un delegado es un tipo que hace referencia a un mtodo. Cuando se asigna un mtodo a un delegado, ste se comporta exactamente como el mtodo. Descriptor de acceso [accessor] Mtodo que establece o recupera el valor de un miembro de datos privado asociado a una propiedad. Las propiedades de lectura y escritura tienen descriptores de acceso get y set. Las propiedades que son de slo lectura pueden tener slo un descriptor de acceso get. Destructor [destructor] Mtodo especial de una clase o estructura que prepara la instancia para su destruccin por el sistema. Evento [event] Miembro de una clase o estructura que enva notificaciones de un cambio. Genricos [generics] Los genricos permiten definir una clase o mtodo definidos con un parmetro de tipo. Cuando el cdigo de cliente crea instancias del tipo, especifica un tipo determinado como un argumento. Herencia [inheritance] C# admite la herencia, de manera que una clase que se deriva de otra clase, conocida como clase base, hereda los mismos mtodos y propiedades. La herencia implica clases base y clases derivadas. IDE [IDE] Entorno de desarrollo integrado. Aplicacin que proporciona la interfaz de usuario unificada para las distintas herramientas de desarrollo como el compilador, depurador, editor de cdigo y diseadores. Interfaz [interface]

MCT: Luis Dueas

Pag 146 de 148

.NET 2 C# .NET
Tipo que contiene slo las firmas de mtodos pblicos, eventos y delegados. Un objeto que hereda la interfaz debe implementar todos los mtodos y eventos definidos en la interfaz. Las clases o estructuras pueden heredar cualquier nmero de interfaces. Iterador [iterator] Un iterador es un mtodo que permite a los consumidores de una clase que contiene una coleccin o matriz utilizar foreach, in (Referencia de C#) para recorrer esa coleccin o matriz. Mtodo [method] Bloque de cdigo con nombre que proporciona el comportamiento de una clase o estructura. Mtodo annimo [anonymous method] Un mtodo annimo es un bloque de cdigo que se pasa como parmetro a un delegado. Miembro [member] Campo, propiedad, mtodo o evento declarado en una clase o estructura. Miembro accesible [accessible member] Miembro al que se puede tener acceso mediante un tipo determinado. Un miembro accesible para un tipo no es necesariamente accesible para otro tipo. Miembro inaccesible [inaccessible member] Miembro al que no se puede tener acceso mediante un tipo determinado. Un miembro inaccesible para un tipo no es necesariamente inaccesible para otro tipo. Modificador de acceso [access modifier] Una palabra clave, como private, protected, internal o public, que restringe el acceso a un tipo o miembro de tipo. Objeto [object] Instancia de una clase. Un objeto existe en memoria y tiene los datos y mtodos que actan sobre los datos. Pila de llamadas [call stack] Serie de llamadas a mtodos que conducen del principio del programa a la instruccin que se ejecuta actualmente en tiempo de ejecucin. Propiedad [property] Miembro de datos al que se obtiene acceso por medio de un descriptor de acceso. Refactorizacin [refactoring] Reutilizar cdigo previamente escrito. El Editor de cdigo de Visual C# Express puede cambiar de manera inteligente el formato del cdigo a, por ejemplo, convertir un bloque de cdigo resaltado en un mtodo. static [static] Una clase o mtodo declarado como static existe sin crearse primero instancias utilizando la palabra clave new. Main() es un mtodo esttico. struct [struct]

MCT: Luis Dueas

Pag 147 de 148

.NET 2 C# .NET
Tipo de datos compuesto que se utiliza normalmente para contener unas variables que tienen alguna relacin lgica. Las estructuras tambin pueden contener mtodos y eventos. Las estructuras no admiten la herencia pero admiten interfaces. Una estructura es un tipo de valor, mientras que una clase es un tipo de referencia. Tipo anidado [nested type] Tipo declarado dentro de la declaracin de otro tipo. Tipo de referencia [reference type] Tipo de datos. Una variable declarada como un tipo de referencia seala una ubicacin donde se almacenan los datos. Tipo de valor [value type] Un tipo de valor es un tipo de datos que se asigna en la pila, a diferencia de un tipo de referencia que est asignado en el montn. Los tipos integrados, entre los que se incluyen los tipos numricos as como el tipo de estructura y el tipo que acepta valores NULL, son todos tipos de valor. El tipo class y el tipo string son tipos de referencia. Tipo inmutable [immutable type] Tipo cuyos datos de instancia (campos y propiedades) no cambian despus de crear la instancia. La mayora de los tipos de valor son inmutables. Tipo mutable [mutable type] Tipo cuyos datos de instancia (campos y propiedades) pueden cambiar despus de crear la instancia. La mayora de los tipos de referencia son mutables.

MCT: Luis Dueas

Pag 148 de 148

You might also like