La colección ha sido modificada; es posible que no se pueda realizar la operación de enumeración.
C# (C-Sharp) es el nuevo lenguaje de programación de Microsoft, conocido como "el primer lenguaje orientado a componentes de la familia C/C++". Sin embargo, a pesar de sus afirmaciones, mucha gente cree que C# se parece más a un clon de Java o a un producto utilizado por Microsoft para reemplazar a Java. ¿Es este el caso?
Los resultados de la comparación en este artículo muestran que C# es más que un simple hermano de Java. Si eres un desarrollador de Java que quiere aprender C# o saber más sobre C#, entonces este artículo es donde debes invertir los primeros 10 minutos.
1. C#, C++ y Java
La especificación del lenguaje C# fue escrita por Anders Hejlsberg y Scott Wiltamuth de Microsoft. En el revuelo actual que rodea a Microsoft, siempre es interesante comparar C# con C++ y Java. Teniendo en cuenta la tendencia actual de la opinión pública en los medios de TI, si sabe que C# está más cerca de Java que de C++, no vale la pena armar un escándalo. Para los lectores que recién se unen a esta discusión, la Tabla 1 a continuación les permite emitir su propio juicio. Obviamente, la conclusión debería ser: aunque Java y C# no son gemelos, la característica principal de C# está más cerca de Java que de C++.
Tabla 1: Comparación de las características más importantes de C#, C++ y Java
Función C# C++ Java
La herencia permite la herencia de una sola clase y permite la implementación de múltiples interfaces La herencia de múltiples clases permite la herencia de una sola clase, lo que permite la implementación de múltiples interfaces
Implementación de interfaz a través de la palabra clave "interface" a través de clases abstractas a través de la palabra clave "interface"
La administración de la memoria la realiza el entorno de tiempo de ejecución. El uso del recolector de basura requiere administración manual. . El soporte de puntero suele ser reemplazado por una referencia, una característica muy común. No es compatible en absoluto. Reemplácelo con una cotización.
La forma compilada del código fuente. NET código de bytes ejecutable del lenguaje intermedio (IL)
Es una única clase base pública
Manejo de excepciones Manejo de excepciones Devolución Manejo de excepciones de error .
Después de comprender las características importantes del lenguaje resumidas en la Tabla 1, siga leyendo para conocer algunas diferencias importantes entre C# y Java.
2. Comparación de especificaciones de lenguaje
2.1. Tipos de datos simples
Los tipos de datos simples (Primitivos) se denominan tipos de valor en C# y están predefinidos por C#. Son tipos de datos más simples que Java. Por ejemplo, C# tiene unidad, que es un entero sin signo. La Tabla 2 enumera todos los tipos de datos predefinidos de C#:
Tabla 2: Tipos de valores en C#
Descripción del tipo
objeto El destino final para todos los tipos Clase base p>
tipo de cadena de cadena; la cadena es una secuencia de caracteres Unicode
sbyte entero de 8 bits con signo
entero corto de 16 bits con signo
int Entero de 32 bits con signo
Entero largo de 64 bits con signo
Entero de bytes de 8 bits sin signo
Entero corto de 16 bits sin signo
uint entero sin signo de 32 bits
ulong entero sin signo de 64 bits
tipo de número flotante de punto flotante de precisión simple
tipo de punto flotante de doble precisión doble
bool Tipo booleano; el valor bool es verdadero o falso
tipo de carácter char; un valor char es un carácter Unicode
decimal Tipo decimal de alta precisión con 28 dígitos significativos
2.2. Constantes
Olvídate del modificador final estático en Java.
En C#, las constantes se pueden declarar utilizando la palabra clave const.
public const int x = 55;
Además, los diseñadores de C# también agregaron la palabra clave readonly. Si el compilador no puede determinar el valor constante en el momento de la compilación, puede utilizar la palabra clave de solo lectura. Los campos de solo lectura solo se pueden configurar mediante un inicializador o un constructor de clases.
2.3. Punto de entrada de una clase pública
En Java, el punto de entrada de una clase pública es un método estático público llamado main. El parámetro del método principal es una matriz de objetos String y no tiene valor de retorno. En C#, el método principal se convierte en el método estático público Main (M mayúscula). El parámetro del método Main también es una matriz de objetos String y no hay ningún valor de retorno, como se muestra en la siguiente declaración de prototipo:
public static void Main(String[] args)
Sin embargo, el método Main de C# no se limita a esto. Si no pasa ningún parámetro al método Main, puede usar una versión sobrecargada del método Main anterior, es decir, la versión sin una lista de parámetros. En otras palabras, el siguiente método Main también es un punto de entrada legal:
public static void Main()
Además, si lo cree necesario, el método Main también puede devolver un int. Por ejemplo, el método Main en el siguiente código devuelve 1:
using System;
public class Hello {
public static int Main() { p>
Console.WriteLine("Done");
return 1;
}
}
Por el contrario, en Es ilegal sobrecargar el método principal en Java.
2.4. Sentencia switch
En Java, la sentencia switch sólo puede manejar números enteros. Pero la declaración de cambio en C# es diferente, también puede manejar variables de caracteres. Considere el siguiente código C# que utiliza una instrucción de cambio para procesar una variable de cadena:
using System;
public class Hello {
public static void Main(String [] args) {
switch (args[0]) {
case "Boss":
Console.WriteLine("¡Buenos días! Siempre estamos listo para ayudarte ¡A tus órdenes! ");
descanso;
case "employee":
Console.WriteLine("¡Buenos días! Ya puedes empezar. ¡funcionando!");
descanso;
predeterminado:
Console.WriteLine("¡Buenos días! ¡Buena suerte!");
break;
}
}
}
A diferencia del switch en Java, la instrucción switch de C# requiere cada bloque case o en el block Proporcione una declaración de interrupción al final o use goto para ir a otras etiquetas de casos dentro del conmutador.
2.5. Declaración foreach
La declaración foreach enumera cada elemento de la colección y ejecuta un bloque de código una vez para cada elemento de la colección. Vea el ejemplo a continuación.
usando System;
clase pública Hola {
public static void Main(String[] args) {
foreach (String args) en args)
Console.WriteLine(arg);
}
}
Si se especifican los parámetros al ejecutar este archivo ejecutable, como como "Hola Peter Kevin Richard", la salida del programa serán las siguientes líneas de texto:
Peter
Kevin
Richard
2.6. C# no tiene el operador >>> desplazamiento
C# admite tipos de variables sin signo como uint y ulong. Por lo tanto, en C#, el operador de desplazamiento a la derecha (es decir, ">>") se trata de manera diferente para tipos de variables sin signo y tipos de variables con signo (como int y long). El desplazamiento hacia la derecha uint y ulong descartan los bits bajos y establecen los bits altos vacantes en cero, pero para las variables de tipo int y long, el operador ">>" descarta los bits bajos. Al mismo tiempo, solo cuando el valor de la variable es positivo. número, ">>" Establece el bit alto vacante en cero si ">>" opera con un número negativo, el bit alto vacante se establece en 1;
No existe ningún tipo de variable sin firmar en Java. Por lo tanto, utilizamos el operador ">>>>" para introducir un bit de signo negativo al desplazarnos hacia la derecha; de lo contrario, utilizamos el operador ">>".
2.7. palabra clave goto
Java no utiliza la palabra clave goto. En C#, goto le permite ir a una etiqueta específica. Sin embargo, C# trata a goto con especial precaución. Por ejemplo, no permite que goto se transfiera al interior de un bloque de instrucciones. En Java, puede reemplazar goto en C# con una declaración etiquetada más pausa o continuar.
2.8. Declarar matrices
En Java, el método de declarar matrices es muy flexible. De hecho, existen muchos métodos legales para declarar matrices. Por ejemplo, las siguientes líneas de código son equivalentes:
int[] x = { 0, 1, 2, 3 };
int x[] = { 0, 1 , 2, 3 };
Pero en C#, solo la primera línea de código es legal y [] no se puede colocar después del nombre de la variable.
2.9. Paquete
En C#, el paquete (Paquete) se llama espacio de nombres. La palabra clave para introducir espacios de nombres en programas C# es "usar". Por ejemplo, la declaración "usando el sistema" introduce el espacio de nombres del sistema.
Sin embargo, a diferencia de Java, C# le permite especificar alias para espacios de nombres o clases en espacios de nombres:
using TheConsole = System.Console;
public class Hola {
public static void Main() {
TheConsole.WriteLine("Usar alias");
}
}
Aunque conceptualmente, los paquetes Java son similares a los espacios de nombres .NET. Sin embargo, los dos se implementan de manera diferente. En Java, el nombre del paquete también es una entidad real, que determina la estructura de directorios en la que se colocan los archivos .java. ¿En la escuela C#?¿锢洢洢洢洼洒鑒?¿tomar?pu?涶iaoqi?¿Lanzar moldes?¿Sacar los libros?¿Sacar las botellas?Plantar y cambiar el halo Xiu锢淼 Thumb Qiu?¿Conferencia Jiao?Wei Wan Ba Zhen T En Java, cada archivo de código fuente puede pertenecer a múltiples espacios de nombres y puede acomodar múltiples clases públicas.
La entidad empaquetada en .NET se llama ensamblado. Cada ensamblaje contiene una estructura manifiesta.
El manifiesto enumera los archivos contenidos en el ensamblado, controla qué tipos y recursos se exponen fuera del ensamblado y asigna referencias a estos tipos y recursos a los archivos que contienen estos tipos y recursos. Los ensamblajes son autónomos. Un ensamblaje se puede colocar en un solo archivo o dividir en varios archivos. Este mecanismo de encapsulación de .NET resuelve el problema que enfrentan los archivos DLL, es decir, el infame problema DLL Hell.
2.10. Paquete predeterminado
En Java, el paquete java.lang es el paquete predeterminado, que se incluye automáticamente sin importación explícita. Por ejemplo, para enviar texto a la consola, puede utilizar el siguiente código:
System.out.println("Hola mundo desde Java"); Paquete predeterminado de C#. Si desea enviar texto a la consola, utilice el método WriteLine del objeto Consola en el espacio de nombres del Sistema. Sin embargo, debes importar todas las clases explícitamente. El código es el siguiente:
using System;
public class Hola {
public static void Main() {
Console. WriteLine(" Hola mundo desde C#");
}
}
2.11, orientado a objetos
Tanto Java como C# son Lenguaje completamente orientado a objetos. En términos de los tres principios de la programación orientada a objetos, los dos lenguajes no podrían estar más cerca.
Herencia: Ambos lenguajes admiten herencia única de clases, pero las clases pueden implementar múltiples interfaces. Todas las clases heredan de una clase base pública.
Encapsulación y visibilidad: Ya sea en Java o C#, puedes decidir si los miembros de la clase son visibles o no. Excepto por el modificador de acceso interno de C#, el mecanismo de visibilidad de los dos es muy similar.
Polimorfismo: tanto Java como C# admiten algunas formas de mecanismos de polimorfismo y sus métodos de implementación son muy similares.
2.12. Accesibilidad
Cada miembro de una clase tiene un tipo específico de accesibilidad. Los modificadores de acceso en C# corresponden básicamente a los de Java, pero hay uno interno extra. En resumen, C# tiene 5 tipos de accesibilidad de la siguiente manera:
Pública: se puede acceder a los miembros desde cualquier código.
Protegido: Solo se puede acceder a los miembros desde clases derivadas.
interno: Solo se puede acceder a los miembros desde dentro de la misma asamblea.
Protegido interno: solo se puede acceder a los miembros desde clases derivadas dentro del mismo ensamblaje.
Privado: Solo se puede acceder a los miembros dentro de la clase actual.
2.13. Clases derivadas
En Java, utilizamos la palabra clave "extiende" para implementar la herencia. C# adopta la sintaxis de derivación de clases de C++. Por ejemplo, el siguiente código muestra cómo derivar la clase principal Control para crear una nueva clase Botón:
Botón de clase pública: Control { }
2.14, clase final
Dado que la palabra clave final no existe en C#, si desea que una clase ya no se derive, puede usar la palabra clave sellada, como se muestra en el siguiente ejemplo:
clase sellada FinalClass { . }
2.15. Interfaz
El concepto de interfaz es muy similar en C# y Java. La palabra clave de interfaz es interfaz. Una interfaz puede ampliar una o más interfaces. Por convención, los nombres de las interfaces comienzan con la letra "I" mayúscula. El siguiente código es un ejemplo de una interfaz C#, que es exactamente igual a la interfaz en Java:
interface IShape { void Draw() }
La sintaxis del extendido. La interfaz es la misma que la de la clase extendida. La sintaxis es la misma.
Por ejemplo, la interfaz IRectangularShape en el siguiente ejemplo extiende la interfaz IShape (es decir, deriva la interfaz IRectangularShape de la interfaz IShape).
interface IRectangularShape: IShape { int GetWidth() }
Si deriva de dos o más interfaces, la lista de nombres de interfaces principales está separada por comas, como se muestra a continuación. El código se muestra:
interfaz INewInterface: IParent1, IParent2 { }
Sin embargo, a diferencia de Java, las interfaces en C# no pueden contener campos.
Tenga en cuenta también que en C#, todos los métodos de la interfaz son métodos públicos de forma predeterminada. En Java, una declaración de método puede tener el modificador público (aunque no es necesario), pero en C# es ilegal especificar explícitamente el modificador público para un método de una interfaz. Por ejemplo, la siguiente interfaz de C# generará un error de compilación.
interfaz IShape { public void Draw();
2.16, operadores is y as
El operador is en C# y la operación instancia de Java Lo mismo como operador, ambos se pueden usar para probar si una instancia de un objeto pertenece a un tipo específico. No existe un operador equivalente en Java al operador as en C#. El operador as es muy similar al operador is, pero es más "agresivo": si el tipo es correcto, el operador as intenta convertir la referencia del objeto bajo prueba en el tipo de destino, de lo contrario, establece la referencia de la variable en nula; .
Para comprender correctamente el operador as, primero considere el uso del operador is en el siguiente ejemplo. Este ejemplo contiene una interfaz IShape y dos clases Rectángulo y Círculo que implementan la interfaz IShape.
usando System;
interfaz IShape {
void draw();
}
clase pública Rectángulo : IShape {
public void draw() {
}
public int GetWidth() {
return 6;
}
}
Círculo de clase pública: IShape {
public void draw() {
}
public int GetRadius() {
return 5;
}
}
clase pública LetsDraw {
public static void Main(String[] args) {
IShape forma = null;
if (args[0] == "rectangle") {
forma = nuevo Rectángulo();
}
else if (args[0] == "círculo") {
forma = nuevo Círculo();
}
si (la forma es Rectángulo) {
Rectángulo rectángulo = (Rectángulo) forma;
Consola. WriteLine("Ancho: " + rectángulo.GetWidth());
}
if (la forma es un círculo) {
Círculo círculo = (círculo) forma ;
Console.WriteLine("Radio : " + círculo.GetRadius());
}
}
} p>
}
p>
Después de compilar el código, el usuario puede ingresar "rectángulo" o "círculo" como parámetro del método principal. Si la entrada del usuario es "círculo", la forma se instancia en un objeto de tipo Círculo; por el contrario, si la entrada del usuario es "rectángulo", la forma se instancia en un objeto de tipo Rectángulo; Posteriormente, el programa utiliza el operador is para probar el tipo de variable de la forma: si la forma es un rectángulo, la forma se convierte en un objeto Rectángulo y llamamos a su método GetWidth si la forma es un círculo, la forma es; convertido en un objeto Circle y llamamos a su método GetRadius.
Si utiliza el operador as, el código anterior se puede cambiar a la siguiente forma:
usando Sistema;
interfaz IShape {
void draw();
}
Rectángulo de clase pública: IShape {
public void draw() {
}
public int GetWidth() {
return 6;
}
}
clase pública Círculo: IShape { p>
public void draw() {
}
public int GetRadius() {
return 5;
}
}
clase pública LetsDraw {
public static void Main(String[] args) {
IShape forma = null;
if (args[0] == "rectángulo") {
forma = nuevo rectángulo();
}
else if (args[0] == "círculo") {
forma = nuevo círculo();
}
Rectángulo rectángulo = forma como rectángulo ;
p>if (rectángulo != nulo) {
Console.WriteLine("Ancho: " + rectángulo.GetWidth());
}
else {
Círculo círculo = forma como círculo;
if (círculo! = nulo)
Console.WriteLine("Radio: " + círculo.GetRadius ());
}
}
}
En la parte en negrita del código anterior, no estamos probando el objeto de forma. En el caso del tipo, use el operador as para convertir la forma en un objeto de tipo Rectángulo. Si la forma resulta ser un Rectángulo, la forma se convierte en un objeto de tipo Rectángulo y se guarda en la variable rectángulo, y luego llamamos a su método GetWidth. Si esta conversión falla, hacemos un segundo intento. Esta vez, la forma se convierte en un objeto de tipo Círculo y se guarda en la variable círculo. Si la forma es de hecho un objeto Círculo, el círculo ahora hace referencia a un objeto Círculo y llamamos a su método GetRadius.
2.17. Biblioteca
C# no tiene su propia biblioteca de clases. Sin embargo, C# disfruta de la biblioteca de clases .NET. Por supuesto, las bibliotecas de clases .NET también se pueden utilizar en otros lenguajes .NET, como VB.NET o JScript.NET. Vale la pena mencionar la clase StringBuilder, que es un complemento de la clase String. La clase StringBuilder es muy similar a la clase StringBuffer de Java.
2.18. Recolección de basura
C++ nos ha hecho darnos cuenta de lo ineficiente y lenta que es la gestión manual de la memoria. Cuando crea un objeto en C++, debe destruirlo manualmente. Cuanto más complejo es el código, más difícil se vuelve esta tarea.
Java utiliza un recolector de basura para resolver este problema. El recolector de basura recolecta objetos que ya no se utilizan y libera memoria. C# también adopta este enfoque. Cabe decir que si también estás desarrollando un nuevo lenguaje POO, seguir este camino es una elección muy natural. C# aún conserva el método de administración de memoria manual de C++, que es adecuado para su uso en situaciones donde la velocidad es extremadamente importante, pero esto no está permitido en Java.
2.19. Manejo de excepciones
Si escuchaste que C# usa un mecanismo de manejo de excepciones similar a Java, no te sorprendería, ¿verdad? En C#, todas las excepciones se derivan de una clase llamada Exception (¿te suena familiar?). Además, al igual que en Java, tienes las conocidas declaraciones try and catch. La clase Exception es parte del espacio de nombres del sistema .NET.
3. Funciones que Java no tiene
C# nació después de que Java maduró. Por lo tanto, no es sorprendente que C# tenga algunas funciones maravillosas que Java no tiene (todavía).
3.1. Enumerador
El enumerador es el tipo de enumeración (Enumerador o contador), que es una colección de constantes relacionadas. Para ser precisos, una declaración de tipo enum define un nombre de tipo para un conjunto de constantes simbólicas relacionadas. Por ejemplo, podría crear un enumerador llamado Fruta y usarlo como tipo de valor de variable, limitando así el rango posible de valores para la variable a aquellos que aparecen en el enumerador.
Demostración de clase pública {
enum público Fruta {
Manzana, Plátano, Cereza, Durián
}
Proceso público vacío(Fruta fruta) {
interruptor (fruta) {
caso Fruta.Apple:
...
romper;
caso Fruta.Plátano:
...
romper;
caso Fruta.Cereza:
...
romper;
caso Fruit.Durian:
...
romper;
}
}
}
En el método Process del ejemplo anterior, aunque puedes usar int como el tipo de variable myVar, usa una enumeración. Después de convertir Fruit, el rango de valores de las variables se limita a los valores de Applet, Banana, Cherry y Durian. En comparación con int, enum es más legible y se explica por sí mismo.
3.2. Estructura
La estructura es muy similar a la clase. Sin embargo, una clase se crea en el montón como un tipo de referencia, mientras que una estructura es un tipo de valor que se almacena en la pila o se incrusta. Por lo tanto, las estructuras son más rápidas que las clases siempre que se utilicen con cuidado. Las estructuras pueden implementar interfaces y tener miembros como clases, pero las estructuras no admiten la herencia.
Sin embargo, el simple hecho de reemplazar clases con estructuras puede provocar pérdidas desastrosas. Esto se debe a que la estructura se pasa por valor. Dado que este método de transferencia requiere copiar el valor en una nueva ubicación, pasar una estructura "gorda" requiere una gran sobrecarga. Para las clases, solo necesitas pasar su referencia al aprobar.
El siguiente es un ejemplo de una estructura. Tenga en cuenta que es muy similar a una clase, simplemente reemplace la palabra "estructura" con "clase" y obtendrá una clase.
estructura Punto {
público int x, y;
público Punto(int x, int y) {
this.x = x;
this.y = y;
}
}
3.3.3.3. Además de tener campos, las clases también pueden tener propiedades. Una propiedad es una característica con nombre asociada con una clase u objeto. Las propiedades son una extensión natural de los dominios; ambos son miembros de clase escritos y nombrados. Sin embargo, a diferencia de los campos, las propiedades no representan ubicaciones de almacenamiento, sino que tienen descriptores de acceso que definen el código que se debe ejecutar para leer o escribir el valor de la propiedad. Por lo tanto, las propiedades proporcionan un mecanismo para asociar acciones con operaciones para leer y escribir valores de propiedades de objetos y permiten calcular valores de propiedades.
En C#, las propiedades se definen mediante la sintaxis de declaración de propiedades. La primera parte de la sintaxis de la declaración de propiedad es muy similar a la declaración de campo, y la segunda parte incluye un procedimiento set y/o un procedimiento get. Por ejemplo, en el siguiente ejemplo, la clase PropertyDemo define una propiedad Prop.
PropertyDemo de clase pública {
propiedad de cadena privada;
propiedad de cadena pública {
obtener {
retorno prop;
}
establecer {
prop = valor;
}
}
}
Si una propiedad permite lectura y escritura, como la propiedad Prop de la clase PropertyDemo, tiene procedimientos de acceso get y set. Cuando leemos el valor de una propiedad, se llama al procedimiento de acceso get; cuando escribimos el valor de la propiedad, se llama al procedimiento de acceso set. Durante el acceso establecido, el nuevo valor del atributo se proporciona en un parámetro de valor implícito.
Las propiedades se pueden leer y escribir usando la misma sintaxis que los campos. Por ejemplo, el siguiente código crea una instancia de una clase PropertyDemo y luego escribe y lee su propiedad Prop.
PropertyDemo pd = new PropertyDemo();
pd.Prop = "123"; // establecer
string s = pd.Prop;
3.4. Pasar parámetros de tipos de datos simples por referencia
En Java, cuando pasas un valor de un tipo de datos simple como parámetro a un método, el parámetro siempre toma el valor. - es decir, el sistema creará una copia del valor del parámetro para el método llamado. En C#, puede pasar un valor de un tipo de datos simple por referencia. En este punto, el método llamado utilizará directamente el valor que se le pasó, es decir, si el valor del parámetro se modifica dentro del método llamado, el valor de la variable original también cambiará.
Al pasar valores por referencia en C#, utilizamos la palabra clave ref. Por ejemplo, si compila y ejecuta el código siguiente, verá el resultado 16 en la consola. Observe cómo el valor i cambia después de pasarlo a ProcessNumber.
usando System;
clase pública PassByReference {
public static void Main(String[] args) {
int i = 8 ;
Número de proceso(ref i);
Console.WriteLine(i);
}
Número de proceso público estático vacío (ref int j) {
j = 16;
}
}
También hay una clave en C# que permite pasar parámetros por referencia La palabra fuera, que es similar a la ref. Sin embargo, cuando se usa out, las variables pasadas como argumentos no necesitan tener valores conocidos antes de pasarlas. En el ejemplo anterior, si el número entero i no se inicializa antes de pasarlo al método ProcessNumber, el código generará un error. Si usa out en lugar de ref, puede pasar un valor no inicializado, como se muestra en el ejemplo modificado a continuación.
usando System;
clase pública PassByReference {
public static void Main(String[] args) {
int i;
Número de proceso(fuera i);
Console.WriteLine(i);
}
Número de proceso público estático vacío (fuera int j) {
j = 16;
}
}
Después de la modificación, aunque el valor i no se inicializa antes de pasarlo al Método ProcessNumber, pero la clase PassByReference se puede compilar correctamente.
3.5. C# conserva punteros
Para los desarrolladores que sienten que pueden usar punteros apropiadamente y están dispuestos a realizar la administración de memoria manualmente, en C#, aún pueden usar ambos. No es seguro o punteros "antiguos" fáciles de usar para mejorar el rendimiento del programa. C# proporciona la capacidad de admitir código "inseguro", que puede manipular directamente punteros y "fijar" objetos para evitar temporalmente que el recolector de basura mueva el objeto. Desde la perspectiva tanto de los desarrolladores como de los usuarios, esta compatibilidad con código "inseguro" es en realidad una característica de seguridad. El código "inseguro" debe marcarse explícitamente con la palabra clave unsafe, de modo que los desarrolladores no puedan utilizar código "inseguro" sin darse cuenta. Al mismo tiempo, el compilador de C# coopera con el motor de ejecución para garantizar que el código "inseguro" no pueda disfrazarse de código seguro.
usando System;
clase UsePointer {
PointerDemo vacío estático inseguro (byte[] arr) {
.
.
}
}
El código inseguro en C# es adecuado para su uso en las siguientes situaciones: cuando la velocidad es extremadamente importante o cuando el objeto debe ser al interactuar con software existente (como objetos COM o código C en forma de DLL).
3.6. Delegado
Un delegado puede considerarse como un puntero de función en C++ u otros lenguajes. Sin embargo, a diferencia de los punteros de función, los proxies en C# están orientados a objetos, son seguros y confiables. Además, los punteros de función solo se pueden utilizar para hacer referencia a funciones estáticas, pero los proxies pueden hacer referencia tanto a métodos estáticos como a métodos de instancia. Los proxies se utilizan para encapsular métodos invocables. Puede escribir un método dentro de una clase y crear un proxy en ese método, después de lo cual el proxy se puede pasar al segundo método. De esta forma, el segundo método puede llamar al primer método.
Un proxy es un tipo de referencia derivado de la clase base pública System.Delegate. Definir y utilizar un proxy implica tres pasos: declaración, creación de instancia e invocación. Los delegados se declaran utilizando la sintaxis de declaración de delegados. Por ejemplo, un proxy que no requiere parámetros y no tiene valor de retorno se puede declarar con el siguiente código:
delegate void TheDelegate()
La sintaxis para crear una instancia de proxy es : utiliza la nueva palabra clave y hace referencia a una instancia o método de clase que debe cumplir con las características especificadas por el agente. Una vez que se crea una instancia del proxy, podemos llamarla usando la sintaxis para llamar a métodos.
3.7. Empaquetado y desempaquetado
En lenguajes de programación orientados a objetos solemos utilizar objetos. Pero para mejorar la velocidad, C# también proporciona tipos de datos simples. Por lo tanto, los programas C# contienen tanto una gran cantidad de objetos como una gran cantidad de valores. En este entorno, conseguir que los dos trabajen juntos es siempre un problema inevitable. Debes tener una forma de comunicar referencias y valores.
En entornos de ejecución C# y .NET, este problema de "comunicación" se resuelve mediante boxing y unboxing. El ajuste es el proceso de hacer que un tipo de valor parezca un tipo de referencia. El ajuste se produce automáticamente cuando se utiliza un tipo de valor (tipo de datos simple) en una situación en la que se requiere o se puede utilizar un objeto. Los pasos para encapsular un valor de tipo de valor incluyen asignar una instancia de objeto y luego copiar el valor de tipo de valor a la instancia de objeto.
Desenvolver realiza la acción opuesta a envolver, convierte un tipo de referencia en un tipo de valor. Los pasos de la operación de desenvolvimiento incluyen primero verificar para confirmar que la instancia del objeto es de hecho un valor empaquetado del tipo de valor dado y luego copiar el valor de la instancia del objeto.
Java maneja este problema de manera ligeramente diferente. Java proporciona un contenedor de clase correspondiente para cada tipo de datos simple. Por ejemplo, la clase Integer se usa para encapsular el tipo int y la clase Byte se usa para encapsular el tipo byte.
Conclusión Este artículo compara C# y Java. Los dos lenguajes son muy similares, sin embargo, decir que C# es un clon de Java puede ser muy exagerado. Conceptos como lenguajes intermedios y orientados a objetos no son nuevos. Si tuviera que diseñar un nuevo lenguaje orientado a objetos y tuviera que ejecutarse dentro de un entorno seguro y administrado, ¿no terminaría con algo similar a C#?