Como posso obter o tipo de dados de uma variável em C #?


92

Como posso descobrir que tipo de dados alguma variável está mantendo? (por exemplo, int, string, char, etc.)

Eu tenho algo assim agora:

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;
        }
    }
}

6
Você já definiu o tipo -int
Jamiec

Não está claro o que você quer dizer com "descobrir o tipo de dados". Normalmente, a resposta é "basta olhar para a assinatura do membro da classe e o tipo é declarado de forma explícita". É sua intenção inspecionar os membros da classe no tempo de execução?
Wiktor Zychla

1
Fora do assunto, mas o que você escreveu aqui é melhor escrito assim com C #: class Person { public string Name { get; set; } }ou class Person { private string m_Name; public string Name { get {return m_Name;} set { m_Name = value; } }. Leia a documentação sobre Propriedades
Steve B

1
Jamiec está certo. A tipagem estática significa que a declaração define seu tipo para sempre. Sua variável n só pode ser do tipo que você declarou ou um tipo herdado. No seu caso específico, você escolheu exibir um int, que é um tipo do qual você não pode herdar, portanto, n só pode ser um int.
Ksempac

Respostas:


117

Há uma questão importante e sutil que nenhum deles aborda diretamente. Existem duas maneiras de considerar o tipo em C #: tipo estático e tipo de tempo de execução .

O tipo estático é o tipo de uma variável em seu código-fonte. É, portanto, um conceito de tempo de compilação. Esse é o tipo que você vê em uma dica de ferramenta ao passar o mouse sobre uma variável ou propriedade em seu ambiente de desenvolvimento.

Você pode obter o tipo estático escrevendo um método genérico auxiliar para permitir que a inferência de tipo cuide disso para você:

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

O tipo de tempo de execução é o tipo de um objeto na memória. Portanto, é um conceito de tempo de execução. Este é o tipo retornado pelo GetType()método.

O tipo de tempo de execução de um objeto é frequentemente diferente do tipo estático da variável, propriedade ou método que o mantém ou retorna. Por exemplo, você pode ter um código como este:

object o = "Some string";

O tipo estático da variável é object, mas em tempo de execução, o tipo do referente da variável é string. Portanto, a próxima linha imprimirá "System.String" no console:

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

Mas, se você passar o mouse sobre a variável oem seu ambiente de desenvolvimento, verá o tipo System.Object(ou a objectpalavra-chave equivalente ). Você também vê o mesmo usando nossa função auxiliar acima:

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

Para variáveis do tipo de valor, como int, double, System.Guid, você sabe que o tipo de tempo de execução será sempre o mesmo que o tipo estático, porque os tipos de valor não pode servir como a classe base para outro tipo; o tipo de valor é garantidamente o tipo mais derivado em sua cadeia de herança. Isso também é verdadeiro para os tipos de referência lacrada: se o tipo estático for um tipo de referência lacrada, o valor de tempo de execução deve ser uma instância desse tipo ou null.

Por outro lado, se o tipo estático da variável for um tipo abstrato, é garantido que o tipo estático e o tipo de tempo de execução serão diferentes.

Para ilustrar isso no 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));

3
então variable.getType()retorna o tipo de tempo de execução (o tipo do lado direito), mas o que retorna o tipo estático (o tipo do lado esquerdo de uma variável)?
Barlop

@barlop que é conhecido em tempo de compilação. Você pode usar typeofpara obter um objeto de tipo em tempo de execução para o tipo estático.
phoog

sim, eu sei tipo estático = tipo de tempo de compilação e tipo de tempo de execução = tipo dinâmico. Embora esteja obtendo o tipo de variável 'a', você não pode fazer typeof(a) se fizer typeof(int)isso retornará int, mas não está verificando a variável 'a' e mostrando o tipo de 'a'. Você poderia dizer que não precisa mostrar o tipo estático de 'a', pode ser, mas o fato é que não está mostrando. Portanto, não vejo como o uso de typeof aqui seja útil.
barlop

4
@barlop, você poderia fazer isso para deixar a inferência de tipo cuidar disso para você:Type GetStaticType < T > (T x) { return typeof(T); }
phoog

1
@Jaquarh como você deve ter notado, switchagora suporta correspondência de padrões para teste de tipo (do tipo runtime, não estático). Em vez de ativar o valor retornado de GetType (), você ativa a variável diretamente.
phoog de

16

É muito simples

variable.GetType().Name

ele retornará o tipo de dados de sua variável


16

De modo geral, você dificilmente precisará fazer comparações de tipo, a menos que esteja fazendo algo com reflexão ou interfaces. Não obstante:

Se você souber o tipo com o qual deseja compará-lo, use os operadores isou as:

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

O asoperador executa uma conversão que retorna nulo se falhar em vez de uma exceção:

TypeIKnow typed = unknownObject as TypeIKnow;

Se você não souber o tipo e quiser apenas informações sobre o tipo de tempo de execução, use o método .GetType ():

Type typeInformation = unknownObject.GetType();

Em versões mais recentes do C #, você pode usar o isoperador para declarar uma variável sem precisar usar as:

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

Anteriormente, você teria que fazer isso:

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

4

Basta segurar o cursor sobre o membro de seu interesse e ver a dica - ela mostrará o tipo de membro:

insira a descrição da imagem aqui



3

Uma opção seria usar um método de extensão auxiliar como segue:

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

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

0

GetType() método

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

0

verifique uma das maneiras simples de fazer isso

// 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.");
        }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.