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

143

我该如何找出某个变量持有的数据类型?(例如:int、string、char等)

现在我有类似于以下的代码:

private static void Main()
{
   var someone = new Person();
   Console.WriteLine(someone.Name.typeOf());
}

public class Person
{
    public int Name { get; set; }
}

7
你已经定义了类型 - “int”。 - Jamiec
这句话不太清楚你所说的“查找数据类型”的意思。通常,答案是“只需查看类成员签名,类型就以明确的方式说明在那里”。你的意图是在运行时检查类成员吗? - Wiktor Zychla
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; } } }。请阅读关于属性的文档。 - Steve B
1
Jamiec是正确的。静态类型意味着声明永久设置了您的类型。您的变量n只能是您声明的类型或继承类型。在您的特定情况下,您选择显示一个int,这是您无法继承的类型,因此n只能是int。 - Ksempac
9个回答

195
其他答案提供了对这个问题的很好帮助,但是有一个重要而微妙的问题没有得到直接解决。在C#中有两种考虑类型的方式:静态类型运行时类型
静态类型是源代码中变量的类型,因此是编译时概念。当您在开发环境中将鼠标悬停在变量或属性上时,可以看到它。
运行时类型是内存中对象的类型,因此是运行时概念。这是由GetType()方法返回的类型。
一个对象的运行时类型经常不同于持有或返回它的变量、属性或方法的静态类型。例如,您可以编写以下代码:
object o = "Some string";

变量的静态类型是 object,但在运行时,变量的引用对象的类型是 string。因此,下一行代码将在控制台上打印出 "System.String":

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

然而,如果你在开发环境中悬停在变量o上,你会看到类型为System.Object(或等效的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));

另一个用户编辑了这个答案,加入了下面评论中的一个通用助手方法,使用类型推断在运行时获取变量的静态类型引用,感谢typeof

Type GetStaticType<T>(T x) => typeof(T);

您可以在上面的示例中使用此函数:
Console.WriteLine(GetStaticType(o)); // prints System.Object

但是这个函数在你想要保护自己免受重构的影响时,其实用处有限。当你写 GetStaticType 的调用时,你已经知道 o 的静态类型是 object。所以你可以直接写:

Console.WriteLine(typeof(object)); // also prints System.Object!

这让我想起了我刚开始工作时遇到的一些代码,类似于:

SomeMethod("".GetType().Name);

替代

SomeMethod("String");

3
variable.getType() 返回变量的运行时类型(即右侧类型),而静态类型(变量左侧的类型)会返回什么? - barlop
@barlop 在编译时已知。您可以使用 typeof 在运行时获取静态类型的类型对象。 - phoog
是的,我知道静态类型 = 编译时类型,而运行时类型 = 动态类型。虽然要获取变量'a'的类型,您不能执行 typeof(a),如果您执行 typeof(int),它将返回int,但不会检查变量'a'并显示'a'的类型。您可以说您不需要显示'a'的静态类型,也许是这样的,但事实是它没有显示出来。所以我不明白在这里使用typeof的用处在哪里。 - barlop
6
你可以使用以下方式来让类型推断为你处理:Type GetStaticType < T > (T x) { return typeof(T); }。请注意,这个代码片段已经是英文的,因此我只需将其翻译成中文并保持原意即可。 - phoog
1
@Jaquarh,你可能已经注意到了,现在switch支持类型匹配以用于类型测试(针对运行时的类型而不是静态的)。你可以直接在变量上进行切换,而不是在GetType()返回的值上进行切换。 - phoog
显示剩余4条评论

24

非常简单

variable.GetType().Name

它将返回您的变量的数据类型。


3
这不正确:object o = "Hi!"; return o.GetType().Name; 返回的是 "String" 而不是 "Object" - phoog

16

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

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

if( unknownObject is TypeIKnow ) { // run code here
< p > 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();
}

4
只需将光标悬停在您感兴趣的成员上,即可查看工具提示 - 它将显示成员的类型: enter image description here

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
使用Object.GetType方法,这将完成任务。
如果您只想知道变量的类型:
var test = (byte)1;
Console.WriteLine(test.GetType());

0

GetType() 方法

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

-1

看看这个简单的方法之一

// 从控制台读取字符串

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.");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接