Jak mogę uzyskać typ danych zmiennej w C #?


94

Jak mogę się dowiedzieć, jaki typ danych zawiera zmienna? (np. int, string, char itp.)

Mam teraz coś takiego:

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
Zdefiniowałeś już typ -int
Jamiec

Nie jest jasne, co masz na myśli mówiąc „znajdź typ danych”. Zwykle odpowiedź brzmi „wystarczy spojrzeć na podpis członka klasy, a typ jest tam określony w wyraźny sposób”. Czy masz zamiar kontrolować członków klasy w czasie wykonywania?
Wiktor Zychla

1
Poza tematem, ale to, co tu napisałeś, lepiej napisać w ten sposób w C #: class Person { public string Name { get; set; } }lub class Person { private string m_Name; public string Name { get {return m_Name;} set { m_Name = value; } }. Przeczytaj dokumentację dotyczącą Właściwości
Steve B

1
Jamiec ma rację. Typowanie statyczne oznacza, że ​​deklaracja ustawia typ na zawsze. Twoja zmienna n może mieć tylko zadeklarowany typ lub typ dziedziczony. W twoim konkretnym przypadku zdecydowałeś się wyświetlić int, jest to typ, z którego nie możesz dziedziczyć, więc n może być tylko liczbą int.
Ksempac

Odpowiedzi:


123

Jest ważna i subtelna kwestia, której żaden z nich nie dotyczy bezpośrednio. Istnieją dwa sposoby rozważania typu w C #: typ statyczny i typ czasu wykonywania .

Typ statyczny to typ zmiennej w kodzie źródłowym. Jest to zatem koncepcja czasu kompilacji. Jest to typ, który widzisz w podpowiedzi po najechaniu kursorem na zmienną lub właściwość w środowisku programistycznym.

Możesz uzyskać typ statyczny, pisząc pomocniczą metodę ogólną, aby umożliwić wnioskowanie o typie za Ciebie:

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

Typ czasu wykonywania to typ obiektu w pamięci. Jest to zatem koncepcja czasu wykonywania. To jest typ zwracany przez GetType()metodę.

Typ czasu wykonywania obiektu często różni się od statycznego typu zmiennej, właściwości lub metody, która go przechowuje lub zwraca. Na przykład możesz mieć taki kod:

object o = "Some string";

Typ statyczny zmiennej to object, ale w czasie wykonywania typem referencji zmiennej jest string. Dlatego w następnej linii na konsoli zostanie wyświetlony tekst „System.String”:

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

Ale jeśli najedziesz kursorem na zmienną ow środowisku programistycznym, zobaczysz typ System.Object(lub równoważne objectsłowo kluczowe). Możesz zobaczyć to samo, korzystając z naszej funkcji pomocniczej z góry:

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

Wartość zmiennych typu, takich jak int, double, System.Guid, wiesz, że typ run-time zawsze będzie taki sam jak typ statyczny, ponieważ typy wartości nie mogą służyć jako klasa bazowa dla innego typu; typ wartości jest typem najbardziej pochodnym w łańcuchu dziedziczenia. Dotyczy to również zapieczętowanych typów odwołań: jeśli typ statyczny jest zapieczętowanym typem odwołania, wartość czasu wykonywania musi być instancją tego typu lub null.

I odwrotnie, jeśli typ statyczny zmiennej jest typem abstrakcyjnym, gwarantuje się, że typ statyczny i typ środowiska wykonawczego będą różne.

Aby zilustrować to w kodzie:

// 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
więc variable.getType()zwraca typ środowiska uruchomieniowego (typ po prawej stronie), ale co zwraca typ statyczny (typ zmiennej po lewej stronie)?
barlop

@barlop, który jest znany w czasie kompilacji. Możesz użyć, typeofaby pobrać obiekt typu w czasie wykonywania dla typu statycznego.
phoog

tak, znam typ statyczny = typ czasu kompilacji i typ środowiska uruchomieniowego = typ dynamiczny. Chociaż otrzymujesz typ zmiennej „a”, nie możesz tego zrobić, typeof(a) jeśli to zrobisz typeof(int), zwróci int, ale nie sprawdza zmiennej „a” i nie pokazuje typu „a”. Można powiedzieć, że nie trzeba pokazywać statycznego typu „a”, tak może być, ale faktem jest, że go nie pokazuje. Nie widzę więc, jak użycie tu typeof jest przydatne.
barlop

4
@barlop, możesz to zrobić, aby wnioskowanie o typie zajęło się tym za Ciebie:Type GetStaticType < T > (T x) { return typeof(T); }
phoog

1
@Jaquarh, jak być może zauważyłeś, switchobsługuje teraz dopasowywanie wzorców do testowania typu (typu uruchomieniowego, a nie statycznego). Zamiast włączać wartość zwracaną przez GetType (), włączasz zmienną bezpośrednio.
phoog

19

To jest bardzo proste

variable.GetType().Name

zwróci twój typ danych twojej zmiennej


16

Ogólnie rzecz biorąc, prawie nigdy nie będziesz musiał porównywać typów, chyba że robisz coś z odbiciem lub interfejsami. Niemniej jednak:

Jeśli znasz typ, z którym chcesz go porównać, użyj operatorów islub as:

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

asOperator wykonuje odlew, który zwraca NULL jeśli nie jest on raczej niż wyjątek:

TypeIKnow typed = unknownObject as TypeIKnow;

Jeśli nie znasz typu i potrzebujesz informacji o typie środowiska uruchomieniowego, użyj metody .GetType ():

Type typeInformation = unknownObject.GetType();

W nowszych wersjach języka C # można użyć isoperatora do zadeklarowania zmiennej bez konieczności używania as:

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

Wcześniej musiałbyś to zrobić:

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

4

Po prostu najedź kursorem na członka, którym jesteś zainteresowany, i zobacz podpowiedź - pokaże typ członka:

wprowadź opis obrazu tutaj



3

Jedną z opcji byłoby użycie metody rozszerzenia pomocnika, takiej jak:

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() metoda

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

0

sprawdź jeden z prostych sposobów, aby to zrobić

// 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.");
        }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.