Come posso ottenere il tipo di dati di una variabile in C #?


92

Come posso sapere quale tipo di dati contiene una variabile? (es. int, string, char, ecc.)

Ho qualcosa di simile ora:

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
Hai già definito il tipo -int
Jamiec

Questo non è chiaro cosa intendi per "scopri il tipo di dati". Normalmente, la risposta è "basta guardare la firma del membro della classe e il tipo è indicato in modo esplicito". Hai intenzione di ispezionare i membri della classe durante il tempo di esecuzione?
Wiktor Zychla

1
Fuori tema, ma quello che hai scritto qui è meglio scritto in questo modo 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; } }. Leggi la documentazione sulle proprietà
Steve B

1
Jamiec ha ragione. La digitazione statica significa che la dichiarazione imposta il tuo tipo per sempre. La variabile n può essere solo del tipo dichiarato o ereditato. Nel tuo caso specifico hai scelto di visualizzare un int, che è un tipo da cui non puoi ereditare, quindi n può essere solo un int.
Ksempac

Risposte:


119

C'è una questione importante e sottile che nessuno di loro affronta direttamente. Esistono due modi per considerare il tipo in C #: tipo statico e tipo in fase di esecuzione .

Il tipo statico è il tipo di una variabile nel codice sorgente. È quindi un concetto in fase di compilazione. Questo è il tipo visualizzato in una descrizione comando quando passi il mouse su una variabile o una proprietà nel tuo ambiente di sviluppo.

Puoi ottenere il tipo statico scrivendo un metodo generico di supporto per lasciare che l'inferenza del tipo se ne occupi per te:

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

Il tipo di runtime è il tipo di un oggetto in memoria. È quindi un concetto di runtime. Questo è il tipo restituito dal GetType()metodo.

Il tipo di runtime di un oggetto è spesso diverso dal tipo statico della variabile, della proprietà o del metodo che lo contiene o lo restituisce. Ad esempio, puoi avere un codice come questo:

object o = "Some string";

Il tipo statico della variabile è object, ma in fase di esecuzione, il tipo di referente della variabile è string. Pertanto, la riga successiva stamperà "System.String" sulla console:

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

Tuttavia, se passi il mouse sulla variabile onel tuo ambiente di sviluppo, vedrai il tipo System.Object(o la objectparola chiave equivalente ). Puoi anche vedere lo stesso usando la nostra funzione di supporto dall'alto:

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

Per le variabili tipo valore, come ad esempio int, double, System.Guid, si sa che il tipo run-time sarà sempre lo stesso tipo statico, perché i tipi di valore non possono servire come classe base per un altro tipo; il tipo di valore è garantito come il tipo più derivato nella sua catena di ereditarietà. Questo vale anche per i tipi di riferimento sigillati: se il tipo statico è un tipo di riferimento sigillato, il valore di runtime deve essere un'istanza di quel tipo o null.

Al contrario, se il tipo statico della variabile è un tipo astratto, è garantito che il tipo statico e il tipo runtime saranno diversi.

Per illustrarlo nel codice:

// 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
quindi variable.getType()restituisce il tipo di runtime (il tipo sul lato destro), ma cosa restituisce il tipo statico (il tipo sul lato sinistro di una variabile)?
barlop

@barlop noto in fase di compilazione. È possibile utilizzare typeofper ottenere un oggetto di tipo in fase di esecuzione per il tipo statico.
phoog

sì, conosco il tipo statico = tipo di tempo di compilazione e il tipo di runtime = tipo dinamico. Anche typeof(a) se stai ottenendo il tipo di variabile 'a', non puoi farlo se lo fai typeof(int)restituirà int, ma non sta controllando la variabile 'a' e mostrandoti il ​​tipo di 'a' .. Potresti dire che tu non è necessario mostrare il tipo statico di "a", potrebbe essere così, ma il fatto è che non lo mostra. Quindi non vedo come l'uso di typeof qui sia utile.
barlop

4
@barlop potresti farlo per lasciare che l'inferenza del tipo se ne occupi per te:Type GetStaticType < T > (T x) { return typeof(T); }
phoog

1
@Jaquarh, come avrai notato, switchora supporta il pattern matching per il test di tipo (di tipo runtime, non statico). Invece di attivare il valore restituito da GetType (), attivare direttamente la variabile.
phoog

18

È molto semplice

variable.GetType().Name

restituirà il tipo di dati della variabile


16

In generale, non avrai quasi mai bisogno di fare confronti di tipo a meno che tu non stia facendo qualcosa con la riflessione o le interfacce. Ciò nonostante:

Se conosci il tipo con cui vuoi confrontarlo, utilizza gli operatori iso as:

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

L' asoperatore esegue un cast che restituisce null se fallisce piuttosto che un'eccezione:

TypeIKnow typed = unknownObject as TypeIKnow;

Se non conosci il tipo e desideri solo informazioni sul tipo di runtime, utilizza il metodo .GetType ():

Type typeInformation = unknownObject.GetType();

Nelle versioni più recenti di C #, puoi usare l' isoperatore per dichiarare una variabile senza bisogno di usare as:

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

In precedenza avresti dovuto fare questo:

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

4

Tieni semplicemente il cursore sul membro che ti interessa e visualizza il suggerimento: mostrerà il tipo di memeber:

inserisci qui la descrizione dell'immagine



3

Un'opzione potrebbe essere quella di utilizzare un metodo di estensione helper come 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() metodo

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

0

controlla uno dei modi più semplici per farlo

// 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.");
        }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.