C#对象类型比较

C#对象类型比较,c#,types,C#,Types,如何比较声明为type的两个对象的类型 我想知道两个对象是同一类型还是来自同一基类 感谢您的帮助 e、 g 如果您希望这两个对象实例属于某种类型,还可以使用“IS”关键字。这也将用于将子类与父类以及实现接口的类等进行比较。但这对类型的类型不起作用 if (objA Is string && objB Is string) // they are the same. public class a {} public class b : a {} b objb = new b(

如何比较声明为type的两个对象的类型

我想知道两个对象是同一类型还是来自同一基类

感谢您的帮助

e、 g

如果您希望这两个对象实例属于某种类型,还可以使用“IS”关键字。这也将用于将子类与父类以及实现接口的类等进行比较。但这对类型的类型不起作用

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

假设
a
b
是两个对象。如果要查看
a
b
是否在同一继承层次结构中,请使用

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
}
如果要检查其中一个是否是另一个的基类,请尝试

如果您知道特定的基类,那么只需使用
is
关键字:

if (a is T && b is T) {
  // Objects are both of type T.
}

否则,您将不得不直接遍历继承层次结构。

不过,这种想法有点问题,因为每个对象(实际上,每个类型)都有一个公共基类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
}

我尝试了以下使用接口和具体类的层次结构。 它沿着其中一个类型的基类链向上走,直到到达“object”,在这里我们检查当前目标类型是否可分配给源类型。 我们还检查这些类型是否具有公共接口。如果他们这样做了,那么他们“是相同的”

希望这有帮助

 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());
    }
}
公共接口IUser
{
int ID{get;set;}
字符串名称{get;set;}
}
公共类网络用户:IUser
{
公共整数ID
{
得到;
设置
}
公共字符串名
{
得到;
设置
}
}
公共类关联:NetworkUser,IUser
{
#区域IUser成员
公共整数ID
{
得到;
设置
}
公共字符串名
{
得到;
设置
}
#端区
}
公共类管理器:NetworkUser,IUser
{
#区域IUser成员
公共整数ID
{
得到;
设置
}
公共字符串名
{
得到;
设置
}
#端区
}
公共课程
{
公共静态bool arame(类型sourceType,类型destinationType)
{
if(sourceType==null | | destinationType==null)
{
返回false;
}
if(sourceType==destinationType)
{
返回true;
}
//沿着继承链向上走,直到到达“object”,在该点检查
//当前目标类型可从源类型分配
类型tempDestinationType=destinationType;
while(tempDestinationType.BaseType!=typeof(对象))
{
tempDestinationType=tempDestinationType.BaseType;
}
if(tempDestinationType.IsAssignableFrom(sourceType))
{
返回true;
}
var query=来自destinationType.GetInterfaces()中的d,在sourceType.GetInterfaces()中加入s
d.Name等于s.Name
选择s;
//如果查询结果不是空的,那么我们有一个公共接口,因此返回true
if(query!=Enumerable.Empty())
{
返回true;
}
返回false;
}
公共静态void Main(字符串[]args)
{
AreName(新经理().GetType(),新员工().GetType());
}
}

我不知道它们可以是什么类型,只需要知道它们是相同的还是来自相同的基类。这只适用于类型的实例,而不适用于类型的类型。+1我不知道方便的函数IsAssignableFrom,我必须记住这一点。反射层次结构中有很多有用的东西!浏览会员名单很有趣——你很有可能找到你需要的东西。不过,一定要阅读文档。例如,如果t是泛型类型参数,u是约束,IsAssignableFrom将返回true。不过,仅供参考,如果这两个类具有相同的基类,则不会返回true。@AdamRobinson:我不确定这是一个有用的区别。每个引用类型都来自System.Object,所以它们都有相同的基类。@John:看到我的答案了吗。显然,一切都源于客体。然而,海报表明,如果知道这些类是否具有相同的基类(我说过你必须决定你要去多远),这对他来说是有价值的,因此我的回答。很好的示例和解释+1我希望有一种方法可以分享一个公认的答案。又是Thx。@Adam:我想知道是否有一种方法可以将我们两种方法结合起来。在(1)到达System.Object(或某个更受限制的派生类型)[fail]或(2)存在匹配[pass]之前,您可以保留在a和b上获取BaseType.GetType()所产生的类型列表。哦,当然可以。这就是为什么我说你必须决定你想在堆栈上运行多远…你也可以运行像MarshalByRefObject这样的一般系统类型,但是,是的,你肯定可以在堆栈上运行得更远。对类型变量执行while()循环,得到其中任何一个变量的基类型可能更容易(我认为不应该同时做这两件事)并以某种方式限制它,或者不允许在系统程序集中使用任何基类型,或者使用一些“跃点”。
 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());
    }
}