如何在C#中获取变量的数据类型?


92

我如何找出某个变量保存的数据类型?(例如,int,string,char等)

我现在有这样的事情:

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
您已经定义了类型int
Jamiec

目前尚不清楚“查找数据类型”的含义。通常,答案是“您只需查看类成员签名,然后在其中以显式方式声明类型”。您打算在运行时检查班级成员吗?
Wiktor Zychla 2012年

1
超出主题范围,但您在此处编写的内容最好使用C#class Person { public string Name { get; set; } }或编写class Person { private string m_Name; public string Name { get {return m_Name;} set { m_Name = value; } }。阅读文档属性
史蒂夫乙

1
Jamiec是对的。静态类型意味着声明将永远设置您的类型。您的变量n只能是您声明的类型,也可以是继承的类型。在您的特定情况下,您选择显示一个int,这是您不能从其继承的类型,因此n只能是一个int。
Ksempac

Answers:


117

有一个重要而细微的问题,它们都不直接解决。在C#中,有两种考虑类型的方式:静态类型运行时类型

静态类型是源代码中变量的类型。因此,它是一个编译时概念。将鼠标悬停在开发环境中的变量或属性上时,会在工具提示中看到这种类型。

您可以通过编写帮助程序泛型方法让类型推断为您处理静态类型来获取静态类型:

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

运行时类型是内存中对象的类型。因此,这是一个运行时概念。这是GetType()方法返回的类型。

对象的运行时类型通常不同于保存或返回它的变量,属性或方法的静态类型。例如,您可以具有以下代码:

object o = "Some string";

变量的静态类型是object,但是在运行时,变量的引用对象的类型是string。因此,下一行将在控制台输出“ System.String”:

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

但是,如果将鼠标悬停o在开发环境中的变量上,则会看到类型System.Object(或等效的object关键字)。您还可以从上方使用我们的辅助功能看到相同的内容:

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

对于价值型的变量,例如intdoubleSystem.Guid,你知道,在运行时类型将永远是一样的静态类型,因为值类型不能作为另一种类型的基类; 值类型保证是其继承链中派生最多的类型。对于密封引用类型也是如此:如果静态类型是密封引用类型,则运行时值必须是该类型的实例或null

相反,如果变量的静态类型是抽象类型,则可以保证静态类型和运行时类型将不同。

为了说明这一点,在代码中:

// 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
所以 variable.getType()返回运行时类型(右侧类型),但是什么返回静态类型(变量的左侧类型)呢?
barlop 2015年

@barlop在编译时是已知的。您可以用来typeof在运行时获取静态类型的类型对象。
phoog

是的,我知道静态类型=编译时间类型,运行时类型=动态类型。虽然重新获得变量的“A”的类型,你不能这样做typeof(a) ,如果你这样做typeof(int)会返回INT,但不检查变量“a”和显示你的“一”。你可以说的类型,你不需要显示静态类型“ a”,也许是这样,但事实是它没有显示它。所以我看不到在这里使用typeof有什么用。
barlop 2015年

4
@barlop,您可以这样做让类型推断为您处理:Type GetStaticType < T > (T x) { return typeof(T); }
phoog

1
您可能已经注意到,@ Jaquarh switch现在支持模式匹配以进行类型测试(运行时类型,不是静态的)。无需打开从GetType()返回的值,而是直接打开变量。
phoog


16

一般来说,除非您使用反射或接口进行某些操作,否则几乎不需要进行类型比较。尽管如此:

如果知道要与之比较的类型,请使用isas运算符:

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

as运营商进行演员,其中返回null如果失败,而不是一个例外:

TypeIKnow typed = unknownObject as TypeIKnow;

如果您不知道类型,而只想要运行时类型信息,请使用.GetType()方法:

Type typeInformation = unknownObject.GetType();

在较新版本的C#中,您可以使用is运算符来声明变量,而无需使用as

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

以前,您必须执行以下操作:

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



3

一种选择是使用如下的帮助程序扩展方法:

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() 方法

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

0

查看执行此操作的简单方法之一

// 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.");
        }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.