Comment puis-je obtenir le type de données d'une variable en C #?


92

Comment puis-je savoir quel type de données contient une variable? (par exemple int, chaîne, char, etc.)

J'ai quelque chose comme ça maintenant:

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
Vous avez déjà défini le type -int
Jamiec

Ce que vous entendez par «trouver le type de données» n'est pas clair. Normalement, la réponse est "il suffit de regarder la signature du membre de classe et le type y est indiqué de manière explicite". Votre intention est-elle d'inspecter les membres de la classe pendant l'exécution?
Wiktor Zychla

1
Hors sujet, mais ce que vous avez écrit ici est mieux écrit comme ça avec 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; } }. Lire la documentation sur Properties
Steve B

1
Jamiec a raison. Le typage statique signifie que la déclaration définit votre type pour toujours. Votre variable n ne peut être que du type que vous avez déclaré ou d'un type hérité. Dans votre cas spécifique, vous avez choisi d'afficher un int, c'est un type dont vous ne pouvez pas hériter, donc n ne peut être qu'un int.
Ksempac

Réponses:


119

Il y a un problème important et subtil qu'aucun d'eux ne traite directement. Il existe deux façons de considérer le type en C #: le type statique et le type au moment de l'exécution .

Le type statique est le type d'une variable dans votre code source. C'est donc un concept au moment de la compilation. Il s'agit du type que vous voyez dans une info-bulle lorsque vous survolez une variable ou une propriété dans votre environnement de développement.

Vous pouvez obtenir un type statique en écrivant une méthode générique d'assistance pour laisser l'inférence de type s'en occuper pour vous:

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

Le type d'exécution est le type d'un objet en mémoire. Il s'agit donc d'un concept d'exécution. C'est le type renvoyé par la GetType()méthode.

Le type d'exécution d'un objet est souvent différent du type statique de la variable, propriété ou méthode qui le contient ou le renvoie. Par exemple, vous pouvez avoir un code comme celui-ci:

object o = "Some string";

Le type statique de la variable est object, mais au moment de l'exécution, le type du référent de la variable est string. Par conséquent, la ligne suivante affichera «System.String» sur la console:

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

Mais, si vous survolez la variable odans votre environnement de développement, vous verrez le type System.Object(ou le objectmot-clé équivalent ). Vous voyez également la même chose en utilisant notre fonction d'assistance ci-dessus:

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

Pour les variables de type valeur, tels que int, double, System.Guid, vous savez que le type d' exécution sera toujours le même que le type statique, car les types de valeur ne peut pas servir de la classe de base pour un autre type; il est garanti que le type valeur est le type le plus dérivé de sa chaîne d'héritage. Cela est également vrai pour les types de référence scellés: si le type statique est un type de référence scellé, la valeur d'exécution doit être une instance de ce type ou null.

Inversement, si le type statique de la variable est un type abstrait, alors il est garanti que le type statique et le type d'exécution seront différents.

Pour illustrer cela dans le code:

// 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
donc variable.getType()renvoie le type d'exécution (le type de droite), mais qu'est-ce qui renvoie le type statique (le type de gauche d'une variable)?
barlop

@barlop qui est connu au moment de la compilation. Vous pouvez utiliser typeofpour obtenir un objet de type au moment de l'exécution pour le type statique.
phoog

oui, je connais le type statique = type de compilation et le type d'exécution = type dynamique. Bien que vous obteniez le type de variable «a», vous ne pouvez pas faire typeof(a) si vous le faites, typeof(int)il renverra int, mais ne vérifie pas la variable «a» et ne vous montre pas le type de «a». Vous pourriez dire que vous pas besoin de montrer le type statique de «a», c'est peut-être le cas, mais le fait est qu'il ne le montre pas. Je ne vois donc pas en quoi l'utilisation de typeof ici est utile.
barlop

4
@barlop vous pouvez faire ceci pour laisser l'inférence de type s'en occuper pour vous:Type GetStaticType < T > (T x) { return typeof(T); }
phoog

1
@Jaquarh comme vous l'avez peut-être remarqué, switchprend désormais en charge la correspondance de modèle pour les tests de type (de type à l'exécution, pas statique). Au lieu d'activer la valeur renvoyée par GetType (), vous activez directement la variable.
phoog

17

C'est très simple

variable.GetType().Name

il renverra votre type de données de votre variable


16

De manière générale, vous n'aurez presque jamais besoin de faire des comparaisons de types, sauf si vous faites quelque chose avec la réflexion ou les interfaces. Toutefois:

Si vous connaissez le type avec lequel vous souhaitez le comparer, utilisez les opérateurs isou as:

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

L' asopérateur effectue un cast qui retourne null en cas d'échec plutôt qu'une exception:

TypeIKnow typed = unknownObject as TypeIKnow;

Si vous ne connaissez pas le type et souhaitez simplement des informations sur le type d'exécution, utilisez la méthode .GetType ():

Type typeInformation = unknownObject.GetType();

Dans les versions plus récentes de C #, vous pouvez utiliser le is opérateur pour déclarer une variable sans avoir besoin d'utiliser as:

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

Auparavant, vous deviez faire ceci:

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

4

Maintenez simplement le curseur sur le membre qui vous intéresse et consultez l'info-bulle - elle affichera le type de membre:

entrez la description de l'image ici



3

Une option serait d'utiliser une méthode d'extension d'assistance comme suit:

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éthode

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

0

découvrez l'un des moyens les plus simples de le faire

// 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.");
        }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.