何时何地使用GetType()或typeof()?

Nik*_*wal 60 .net c# types typeof gettype

为什么会这样

if (mycontrol.GetType() == typeof(TextBox))
{} 
Run Code Online (Sandbox Code Playgroud)

这不是吗?

Type tp = typeof(mycontrol);
Run Code Online (Sandbox Code Playgroud)

但这很有效

Type tp = mycontrol.GetType();
Run Code Online (Sandbox Code Playgroud)

我自己使用is运算符来检查类型,但是当我使用typeof()和时,我的理解失败了GetType()

何时何地使用GetType()typeof()

Jon*_*eet 100

typeof是一个运算符,用于获取在编译时已知的类型(或至少是泛型类型参数).操作数typeof始终是类型或类型参数的名称 - 从不是具有值的表达式(例如变量).有关更多详细信息,请参阅C#语言规范.

GetType()是一个调用单个对象的方法,用于获取对象的执行时类型.

请注意,除非您想要实际使用的实例TextBox(而不是子类的实例),否则通常使用:

if (myControl is TextBox)
{
    // Whatever
}
Run Code Online (Sandbox Code Playgroud)

要么

TextBox tb = myControl as TextBox;
if (tb != null)
{
    // Use tb
}
Run Code Online (Sandbox Code Playgroud)

  • 你的行''typeof的操作数总是类型或类型参数的名称 - 永远不会是带有值的表达式(例如变量)'`是我问题的完美答案.谢谢你的协助. (6认同)

Oli*_*bes 49

typeof应用于编译时已知的类型或泛型类型参数的名称.GetType在运行时调用对象.在这两种情况下,结果都是System.Type包含类型元信息的类型的对象.

如果你有

string s = "hello";

Type t1 = typeof(string);
Type t2 = s.GetType();
Run Code Online (Sandbox Code Playgroud)

这两行是有效的

object obj = "hello";

Type t1 = typeof(object); // ==> object
Type t2 = obj.GetType();  // ==> string!
Run Code Online (Sandbox Code Playgroud)

if (mycontrol is TextBox)
Run Code Online (Sandbox Code Playgroud)

这两行是有效的

if (mycontrol.GetType() == typeof(TextBox))    
Run Code Online (Sandbox Code Playgroud)

即,变量的编译时类型(静态类型)与t1 == t2 ==> true引用的对象的运行时类型(动态类型)不同t1 == t2 ==> false.(这里"动态"与关键字无关obj!)


测试类型

但是,如果您只想知道是否obj是一个,mycontrol那么您可以简单地进行测试

public class MySpecializedTextBox : TextBox
{
}

MySpecializedTextBox specialized = new MySpecializedTextBox();
if (specialized is TextBox)       ==> true

if (specialized.GetType() == typeof(TextBox))        ==> false
Run Code Online (Sandbox Code Playgroud)

请注意,这并不完全等同于

if (obj is T) {
    T x = (T)obj; // The casting tests, whether obj is T again!
    ...
}
Run Code Online (Sandbox Code Playgroud)

因为TextBox可以有一个派生自的类型mycontrol.在那种情况下,第一次比较产生TextBox第二次true!在大多数情况下,第一个也更容易的变体是OK,因为从一个控件派生的false继承了所有的东西TextBox,可能会增加更多,因此赋值兼容TextBox.

T x = obj as T;
if (x != null) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

铸件

如果您有以下测试,然后是演员,T可以为空...

if (obj is T t) {
    // t is a variable of type T having a non-null value.
    ...
}
Run Code Online (Sandbox Code Playgroud)

...你可以把它改成......

if (o is int? ni) ===> does NOT compile!
Run Code Online (Sandbox Code Playgroud)

测试值是否属于给定类型和强制转换(再次涉及相同的测试)对于长继承链来说都是耗时的.使用TextBox运算符然后进行测试as更具性能.

从C#7.0开始,您可以使用模式匹配来简化代码:

if (o is int i) ===> OK!
Run Code Online (Sandbox Code Playgroud)


Fr3*_*dan 8

typeOf是一个C#关键字,当您拥有该类的名称时使用.它在编译时计算,因此不能在运行时创建的实例上使用.GetType是可以在实例上使用的对象类的方法.


Jon*_*art 5

您可能会发现使用is关键字更容易:

if (mycontrol is TextBox)
Run Code Online (Sandbox Code Playgroud)

  • @NikhilAgrawal:如果你已经知道一些明显的答案,你应该在问题中这样说,以避免浪费人们的时间.请阅读http://tinyurl.com/so-hints (6认同)