如何比较声明为type的两个对象的类型。
我想知道两个对象是相同类型还是来自同一个基类。
感谢任何帮助。
e.g。
private bool AreSame(Type a, Type b) {
}
答案 0 :(得分:85)
说a
和b
是两个对象。如果您想查看a
和b
是否属于同一继承层次结构,请使用 Type.IsAssignableFrom
:
var t = a.GetType();
var u = b.GetType();
if (t.IsAssignableFrom(u) || u.IsAssignableFrom(t)) {
// x.IsAssignableFrom(y) returns true if:
// (1) x and y are the same type
// (2) x and y are in the same inheritance hierarchy
// (3) y is implemented by x
// (4) y is a generic type parameter and one of its constraints is x
}
如果您想检查一个是否是另一个的基类,请尝试 Type.IsSubclassOf
。
如果您知道特定的基类,那么只需使用is
关键字:
if (a is T && b is T) {
// Objects are both of type T.
}
否则,您必须直接遍历继承层次结构。
答案 1 :(得分:31)
但是,这个想法存在一些问题,因为每个对象(实际上,每种类型)都有一个共同的基类Object。您需要定义的是您想要继续进行的继承链(无论它们是相同的还是它们具有相同的直接父级,或者一个是另一个的直接父级,等等)并且执行检查那样。 IsAssignableFrom
对于确定类型是否彼此兼容非常有用,但如果它们具有相同的父级,则无法完全确定(如果这是您所追求的)。
如果你的严格标准是函数应该返回true,如果......
您可以使用
private bool AreSame(Type a, Type b)
{
if(a == b) return true; // Either both are null or they are the same type
if(a == null || b == null) return false;
if(a.IsSubclassOf(b) || b.IsSubclassOf(a)) return true; // One inherits from the other
return a.BaseType == b.BaseType; // They have the same immediate parent
}
答案 2 :(得分:13)
如果您希望两个对象实例属于某种类型,也可以使用“IS”关键字。这也可用于将子类与父类以及实现接口等的类进行比较。这不适用于Type类型的类型。
if (objA Is string && objB Is string)
// they are the same.
public class a {}
public class b : a {}
b objb = new b();
if (objb Is a)
// they are of the same via inheritance
答案 3 :(得分:2)
我使用接口和具体类的层次结构尝试了以下内容。 它走向其中一个类型的基类链,直到它到达“对象”,我们检查当前目标类型是否可以分配给源类型。 我们还检查类型是否具有公共接口。如果他们这样做,那么他们'AreSame'
希望这有帮助。
public interface IUser
{
int ID { get; set; }
string Name { get; set; }
}
public class NetworkUser : IUser
{
public int ID
{
get;
set;
}
public string Name
{
get;
set;
}
}
public class Associate : NetworkUser,IUser
{
#region IUser Members
public int ID
{
get;
set;
}
public string Name
{
get;
set;
}
#endregion
}
public class Manager : NetworkUser,IUser
{
#region IUser Members
public int ID
{
get;
set;
}
public string Name
{
get;
set;
}
#endregion
}
public class Program
{
public static bool AreSame(Type sourceType, Type destinationType)
{
if (sourceType == null || destinationType == null)
{
return false;
}
if (sourceType == destinationType)
{
return true;
}
//walk up the inheritance chain till we reach 'object' at which point check if
//the current destination type is assignable from the source type
Type tempDestinationType = destinationType;
while (tempDestinationType.BaseType != typeof(object))
{
tempDestinationType = tempDestinationType.BaseType;
}
if( tempDestinationType.IsAssignableFrom(sourceType))
{
return true;
}
var query = from d in destinationType.GetInterfaces() join s in sourceType.GetInterfaces()
on d.Name equals s.Name
select s;
//if the results of the query are not empty then we have a common interface , so return true
if (query != Enumerable.Empty<Type>())
{
return true;
}
return false;
}
public static void Main(string[] args)
{
AreSame(new Manager().GetType(), new Associate().GetType());
}
}