2010-01-21 15 views
14

Hace unos días, decidí empezar a aprender C#. Entonces, obtuve un libro y comencé a leer y practicar con código. Me sorprendió cuando vi que string en C# se considera un tipo primitivo.¿Por qué los tipos primitivos en C# tienen sus propias operaciones?

Pero estaba más sorprendido cuando vi que string, así como todos los otros tipos primitivos en C# tienen operaciones. Soy un desarrollador de Java y entendí que los tipos de datos primitivos no tienen operaciones, solo las clases tienen. Pero en C#, la siguiente es válida:

string name = "alex"; 
Console.WriteLine(name.ToUpper()); 

¿Cómo es esto posible? ¿Son realmente primitivos? ¿Que me estoy perdiendo aqui?

+0

Mal ejemplo, dado que en Java String es un objeto, por lo que "abc" .toString() funciona en Java como lo hace "abc" .ToString() en C# Una distinción es que 123.toString() no funcionará en Java , mientras que 123.ToString() funcionará en C# Entonces podrías preguntar por qué int (que es una primitiva en C# Console.WriteLine (typeof (int) .IsPrimitive) // verdadero tiene métodos. – barlop

Respuesta

29

string no es un tipo primitivo en C#. Es uno de los dos tipos de referencia predefinidos (es decir, parte de la especificación del lenguaje) en C# (el otro es object).Los tipos de primitivas en C# son Boolean (bool), Byte (byte), SByte (sbyte), Int16 (short), UInt16, Int32 (int), UInt32 (uint), Int64 (long), UInt64 (ulong), IntPtr, UIntPtr, Char (char), Double (double) y Single (single). Tenga en cuenta que la especificación establece que "también es posible utilizar estructuras y operador sobrecarga para implementar nuevos tipos‘’en el lenguaje C#" primitivos pero eso es typeof(MyStruct).IsPrimitivefalse si MyStruct es una struct definida por el usuario.

Recibí un libro y comencé a leer y practicar con el código. Me sorprendió cuando vi que la cuerda en C# se considera un tipo primitivo.

El libro dice esto? ¿Cuál libro?

Soy desarrollador de Java y entendí que los tipos de datos primitivos no tienen operaciones, solo las clases tienen.

Simple y llanamente, C# y Java son idiomas diferentes. En C# existe la noción de object de la que deriva casi todo (sí, hay excepciones, la más importante de las cuales son las interfaces). Desde object hay un tipo derivado llamado ValueType. Los derivados de ValueType son struct s que tienen semántica de valor. Todos los demás derivados de object son tipos de referencia. Todos estos object s encapsulan datos y comportamiento (es decir, pueden tener métodos).

string name = "alex";

Console.WriteLine(name.ToUpper());

¿Cómo es esto posible?

No entiendo su confusión con este fragmento de código. name es una instancia de string que está definitivamente asignada por la cadena literal "alex" y estamos invocando una de las sobrecargas del método String.ToUpper en name. A continuación, se invoca la sobrecarga de Console.WriteLine que acepta una instancia de string. Incluso puede hacer esto

Console.WriteLine("alex".ToUpper()); 

¿Son realmente primitivas?

No. string no es un primitivo.

¿Qué es lo que falta aquí?

That C# y Java son lenguajes de programación relacionados pero muy diferentes.

+3

Tienes razón, después de investigar un poco (y leer todas tus respuestas aquí) descubrí que no hay primitivos en C#.No me confundieron con el código, solo estaba confundido de que se te permite realizar operaciones en tipos como int. Por ejemplo, int i = 5; i.ToString(); – Alex

+3

'ToString' es un método' virtual' definido en la clase 'object' de la cual' ValueType' deriva de la cual 'Int32' derives (' int' es una palabra clave reservada en C# que es la abreviatura de 'Int32'). 'Int32' proporciona un' override' de 'ToString'. – jason

+1

+1 Muy buena respuesta. (Por cierto, aquí hay una verificación rápida de su afirmación de que 'String' no es un tipo primitivo:' typeof (String) .IsPrimitive') –

3

Se alias a sus tipos coincidentes de espacio de nombres del sistema en .Net. He aquí un resumen de la lista de alias para los tipos de valor en .Net:

+1

No hay boxeo/unboxing con cadena, es un tipo de referencia. –

+0

@Bruno Reis: gracias por la captura, a menudo me olvido de esto, agregué una referencia completa de los que hacen caja/unbox en caso de que sea útil para alguien más tarde. –

+0

Todavía está mal: ** boxeo ** es tratando un tipo de valor como 'Objeto '. Como se mencionó, ** Int32 es lo mismo que int **. Si" lanzas "un' int' a un 'Int32', no hay absolutamente ningún boxeo. El boxeo se convierte en objeto . Su lista describe los alias tipo, pero tiene absolutamente nothi ng que ver con el boxeo/unboxing. Debe revisar estos conceptos. –

13

string, en C#, es una clase - es un alias para System.String.

Sin embargo, todos los tipos en .NET tienen métodos. Está realmente orientado a objetos, y todo se deriva de System.Object, que también significa que el methods of System.Object funciona en cada tipo en C#.

+0

¿Qué hay de las estructuras (como 'int' aka' Int32' y otros tipos de valores son estructuras)? Según entiendo, no admiten la herencia. ¿Todavía se derivan de 'System.Object'? –

+0

@divo: Toda 'struct' deriva de' System.ValueType' que se deriva de 'System.Object' y están implícitamente' sealed' (lo que significa que no se pueden derivar de). – jason

+0

Aliasing and Herencia para la posteridad: C# string = System.String (clase)> System.Object | C# int = System.Int32 (struct)> System.ValueType> System.Object | Siempre termina en System.Object. Vea los métodos de System.Object aquí http://msdn.microsoft.com/en-us/library/system.object_members.aspx y vea estos en cualquier instancia o valor en su aplicación. –

4

La respuesta breve es que no son realmente primitivos. El compilador cambiará su string con un objeto String.

+0

'cadena' es solo una palabra clave que es un alias para' System.String'. – jason

+0

@Jason - ¿No es que todo es un alias? ¿Algo que sea efectivamente un nombre de marcador de lugar para alguna otra cosa * real *? En otras palabras, ¿no es lo que estás diciendo lógicamente lo mismo que decir que el compilador cambia 'cadena' a' System.String'? Ahora no estoy seguro de si sucede al compilar para CIL o cuando el CIL está JIT en tiempo de ejecución, pero en algún momento una 'cadena' ** es ** un' System.String' ¿verdad? – Alconja

+0

Supongo que simplemente entendí mal lo que quería decir con "el compilador con cambiar su' cadena 'con un objeto 'String'." Pensé que estabas diciendo que los dos son tipos diferentes y el compilador solo está usando 'String' cuando dices' string' pero me doy cuenta ahora (en función de tu comentario) que eso no es lo que querías decir. Mis disculpas; Su comprensión es correcta. Sucede en el momento de la compilación; eso está reemplazando todas las instancias de 'string' con' String' en tu código o viceversa emitirá exactamente la misma IL. – jason

4

Como C# representa todos los tipos de datos primitivos como objetos, es posible llamar a un método de objeto en un tipo de datos primitivo. (Fuente: MSDN - Data Types - C# vs Java)

Cuestiones relacionadas