¿Cómo puedo obtener el tipo de datos de una variable en C #?

92

¿Cómo puedo saber qué tipo de datos contiene alguna variable? (por ejemplo, int, string, char, etc.)

Tengo algo como esto ahora:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Testing
{
    class Program
    {
        static void Main()
        {
            Person someone = new Person();
            someone.setName(22);
            int n = someone.getName();
            Console.WriteLine(n.typeOf());
        }
    }

    class Person
    {
        public int name;

        public void setName(int name)
        {
            this.name = name;
        }

        public int getName()
        {
            return this.name;
        }
    }
}
Limeni
fuente
6
Ya definiste el tipo -int
Jamiec
No está claro a qué se refiere con "averiguar el tipo de datos". Normalmente, la respuesta es "basta con mirar la firma del miembro de clase y el tipo se indica allí de forma explícita". ¿Tiene la intención de inspeccionar a los miembros de la clase durante el tiempo de ejecución?
Wiktor Zychla
1
Fuera de tema, pero lo que escribió aquí está mejor escrito así con C #: class Person { public string Name { get; set; } }o class Person { private string m_Name; public string Name { get {return m_Name;} set { m_Name = value; } }. Lea la documentación sobre Propiedades
Steve B
1
Jamiec tiene razón. La escritura estática significa que la declaración establece su tipo para siempre. Su variable n solo puede ser del tipo que declaró, o un tipo heredado. En su caso específico, eligió mostrar un int, ese es un tipo del que no puede heredar, por lo que n solo puede ser un int.
Ksempac

Respuestas:

119

Hay un tema importante y sutil que ninguno de ellos aborda directamente. Hay dos formas de considerar el tipo en C #: tipo estático y tipo en tiempo de ejecución .

El tipo estático es el tipo de variable en su código fuente. Por tanto, es un concepto en tiempo de compilación. Este es el tipo que ve en una información sobre herramientas cuando pasa el cursor sobre una variable o propiedad en su entorno de desarrollo.

Puede obtener un tipo estático escribiendo un método genérico auxiliar para permitir que la inferencia de tipo se encargue de ello por usted:

   Type GetStaticType<T>(T x) { return typeof(T); }

El tipo de tiempo de ejecución es el tipo de un objeto en la memoria. Por tanto, es un concepto de tiempo de ejecución. Este es el tipo devuelto por el GetType()método.

El tipo de tiempo de ejecución de un objeto suele ser diferente del tipo estático de la variable, propiedad o método que lo contiene o lo devuelve. Por ejemplo, puede tener un código como este:

object o = "Some string";

El tipo estático de la variable es object, pero en tiempo de ejecución, el tipo de referencia de la variable es string. Por lo tanto, la siguiente línea imprimirá "System.String" en la consola:

Console.WriteLine(o.GetType()); // prints System.String

Pero, si pasa el cursor sobre la variable oen su entorno de desarrollo, verá el tipo System.Object(o la objectpalabra clave equivalente ). También ve lo mismo usando nuestra función auxiliar desde arriba:

Console.WriteLine(GetStaticType(o)); // prints System.Object

Para las variables de tipo valor, tales como int, double, System.Guid, usted sabe que el tipo de tiempo de ejecución siempre será el mismo que el tipo estático, debido a los tipos de valor no pueden servir como clase base para otro tipo; se garantiza que el tipo de valor será el tipo más derivado en su cadena de herencia. Esto también es cierto para los tipos de referencia sellados: si el tipo estático es un tipo de referencia sellada, el valor de tiempo de ejecución debe ser una instancia de ese tipo o null.

Por el contrario, si el tipo estático de la variable es un tipo abstracto, se garantiza que el tipo estático y el tipo de tiempo de ejecución serán diferentes.

Para ilustrar eso en el código:

// int is a value type
int i = 0;
// Prints True for any value of i
Console.WriteLine(i.GetType() == typeof(int));

// string is a sealed reference type
string s = "Foo";
// Prints True for any value of s
Console.WriteLine(s == null || s.GetType() == typeof(string));

// object is an unsealed reference type
object o = new FileInfo("C:\\f.txt");
// Prints False, but could be true for some values of o
Console.WriteLine(o == null || o.GetType() == typeof(object));

// FileSystemInfo is an abstract type
FileSystemInfo fsi = new DirectoryInfo("C:\\");
// Prints False for all non-null values of fsi
Console.WriteLine(fsi == null || fsi.GetType() == typeof(FileSystemInfo));
phoog
fuente
3
por lo que variable.getType()devuelve el tipo de tiempo de ejecución (la mano de tipo lado derecho), pero lo que devuelve el tipo estático (la mano de tipo lado izquierdo de una variable)?
barlop
@barlop que se conoce en tiempo de compilación. Puede usar typeofpara obtener un objeto de tipo en tiempo de ejecución para el tipo estático.
phoog
sí, sé tipo estático = tipo de tiempo de compilación y tipo de tiempo de ejecución = tipo dinámico. Aunque está obteniendo el tipo de variable 'a', no puede hacerlo typeof(a) si lo hace typeof(int), devolverá int, pero no está verificando la variable 'a' y le muestra el tipo de 'a'. Podría decir que no es necesario mostrar el tipo estático de 'a', eso puede ser así, pero el hecho es que no lo muestra. Entonces no veo cómo el uso de typeof aquí es útil.
barlop
4
@barlop, podría hacer esto para que la inferencia de tipo se encargue de ello:Type GetStaticType < T > (T x) { return typeof(T); }
phoog
1
@Jaquarh, como habrás notado, switchahora admite la coincidencia de patrones para pruebas de tipo (de tipo de tiempo de ejecución, no estático). En lugar de activar el valor devuelto por GetType (), activa la variable directamente.
phoog
18

Es muy simple

variable.GetType().Name

devolverá su tipo de datos de su variable

Sagar Chavan
fuente
16

En términos generales, casi nunca necesitará hacer comparaciones de tipos a menos que esté haciendo algo con reflexión o interfaces. Sin embargo:

Si conoce el tipo con el que desea compararlo, use los operadores iso as:

if( unknownObject is TypeIKnow ) { // run code here

El asoperador realiza una conversión que devuelve nulo si falla en lugar de una excepción:

TypeIKnow typed = unknownObject as TypeIKnow;

Si no conoce el tipo y solo desea información sobre el tipo de tiempo de ejecución, use el método .GetType ():

Type typeInformation = unknownObject.GetType();

En las versiones más recientes de C #, puede usar el isoperador para declarar una variable sin necesidad de usar as:

if( unknownObject is TypeIKnow knownObject ) {
    knownObject.SomeMember();
}

Previamente tendrías que hacer esto:

TypeIKnow knownObject;
if( (knownObject = unknownObject as TypeIKnow) != null ) {
    knownObject.SomeMember();
}
Dai
fuente
4

Simplemente mantenga el cursor sobre el miembro que le interesa y vea la información sobre herramientas; mostrará el tipo de miembro:

ingrese la descripción de la imagen aquí

Sergey Berezovskiy
fuente
3

Una opción sería utilizar un método de extensión auxiliar como el siguiente:

public static class MyExtensions
{
    public static System.Type Type<T>(this T v)=>typeof(T);
}

var i=0;
console.WriteLine(i.Type().FullName);
Acerby
fuente
0

GetType() método

int n=34;
Console.WriteLine(n.GetType());
string name="Smome";
Console.WriteLine(name.GetType());
Shyju
fuente
0

echa un vistazo a una de las formas sencillas de hacer esto

// Read string from console
        string line = Console.ReadLine(); 
        int valueInt;
        float valueFloat;
        if (int.TryParse(line, out valueInt)) // Try to parse the string as an integer
        {
            Console.Write("This input is of type Integer.");
        }
        else if (float.TryParse(line, out valueFloat)) 
        {
            Console.Write("This input is of type Float.");
        }
        else
        {
            Console.WriteLine("This input is of type string.");
        }
Kiran Solkar
fuente