【发布时间】:2011-03-25 00:09:48
【问题描述】:
如何在 C# 中在运行时检查对象是否属于某种类型?
【问题讨论】:
如何在 C# 中在运行时检查对象是否属于某种类型?
【问题讨论】:
您可以使用 is 关键字。例如:
using System;
class CApp
{
public static void Main()
{
string s = "fred";
long i = 10;
Console.WriteLine( "{0} is {1}an integer", s, (IsInteger(s) ? "" : "not ") );
Console.WriteLine( "{0} is {1}an integer", i, (IsInteger(i) ? "" : "not ") );
}
static bool IsInteger( object obj )
{
if( obj is int || obj is long )
return true;
else
return false;
}
}
产生输出:
fred is not an integer
10 is an integer
【讨论】:
is 通常意味着两个演员,而一个就足够了。这就是为什么它不经常使用的原因。诚然,性能影响可能在 99.99% 的情况下难以察觉。
is' or GetType()' 可能是正确的解决方案。有关包括代码在内的差异的详细信息,请参阅我的答案。
myobject.GetType()
【讨论】:
obj.GetType() 返回类型
【讨论】:
object obj = null; obj.GetType();,会抛出 NullReferenceException
使用typeof 关键字:
System.Type type = typeof(int);
【讨论】:
MyType myObjectType = argument as MyType;
if(myObjectType != null)
{
// this is the type
}
else
{
// nope
}
包括空检查
编辑:错误更正
【讨论】:
MyType myType = myObject as MyType;,然后检查myType是否为空;这并不意味着myObject 是MyType,它只是意味着它可以分配给它。这是一个重要的区别。
我无法添加 cmets,所以我必须添加这个作为答案。请记住,根据文档 (http://msdn.microsoft.com/en-us/library/scekt9xw%28VS.80%29.aspx):
一个 is 表达式的计算结果为 true if 提供的表达式是非空的, 并且提供的对象可以转换为 提供的类型而不引起 抛出异常。
这与使用 GetType 检查类型不同。
【讨论】:
根据您的用例,“is”将无法按预期工作。取一个派生自类 Bar 的类 Foo。创建 Foo 类型的对象 obj。 'obj is Foo' 和 'obj is Bar' 都将返回 true。但是,如果您使用 GetType() 并与 typeof(Foo) 和 typeof(Bar) 进行比较,结果会有所不同。
解释是here,这里有一段源代码展示了这种差异:
using System;
namespace ConsoleApp {
public class Bar {
}
public class Foo : Bar {
}
class Program {
static void Main(string[] args) {
var obj = new Foo();
var isBoth = obj is Bar && obj is Foo;
var isNotBoth = obj.GetType().Equals(typeof(Bar)) && obj.GetType().Equals(typeof(Foo));
Console.Out.WriteLine("Using 'is': " + isBoth);
Console.Out.WriteLine("Using 'GetType()': " + isNotBoth);
}
}
}
【讨论】:
类型信息运算符(as, is, typeof): http://msdn.microsoft.com/en-us/library/6a71f45d(VS.71).aspx
Object.GetType() 方法。
请记住,您可能必须处理继承层次结构。如果你有一个像 obj.GetType() == typeof(MyClass) 这样的检查,如果 obj 是从 MyClass 派生的东西,这可能会失败。
【讨论】:
您也可以在 c# 7 (pattern matching) 中使用 switch/case。
string DoubleMe(Object o)
{
switch (o)
{
case String s:
return s + s;
case Int32 i:
return (i + i).ToString();
default:
return "type which cannot double.";
}
}
void Main()
{
var s= "Abc";
var i= 123;
var now = DateTime.Now;
DoubleMe(s).Dump();
DoubleMe(i).Dump();
DoubleMe(now).Dump();
}
【讨论】: