简体   繁体   English

C# Object 型号比较

[英]C# Object Type Comparison

How can I compare the types of two objects declared as type.如何比较声明为类型的两个对象的类型。

I want to know if two objects are of the same type or from the same base class.我想知道两个对象是同一类型还是来自同一基础 class。

Any help is appreciated.任何帮助表示赞赏。

eg例如

private bool AreSame(Type a, Type b) {

}

Say a and b are the two objects.假设ab是两个对象。 If you want to see if a and b are in the same inheritance hierarchy, then use Type.IsAssignableFrom :如果您想查看ab是否在同一个 inheritance 层次结构中,请使用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
}

If you want to check if one is a base class of the other, then try Type.IsSubclassOf .如果您想检查一个是否是另一个的基础 class,请尝试Type.IsSubclassOf

If you know the specific base class, then just use the is keyword:如果您知道具体的基数 class,那么只需使用is关键字:

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

Otherwise, you'll have to walk the inheritance hierarchy directly.否则,您必须直接遍历 inheritance 层次结构。

There's a bit of a problem with this idea, though, as every object (and, indeed, every type) DOES have a common base class, Object.不过,这个想法有一点问题,因为每个 object(实际上,每个类型)都有一个共同的基础 class、Object。 What you need to define is how far up the chain of inheritance you want to go (whether it's they're either the same or they have the same immediate parent, or one is the immediate parent of the other, etc.) and do your checks that way.您需要定义的是您想要 go 的 inheritance 链上多远(无论它们是相同的还是具有相同的直系父级,或者一个是另一个的直系父级,等等)并执行您的那样检查。 IsAssignableFrom is useful for determining if types are compatible with one another, but won't fully establish if they have the same parent (if that's what you're after). IsAssignableFrom对于确定类型是否相互兼容很有用,但不能完全确定它们是否具有相同的父级(如果这是您所追求的)。

If your strict criteria is that the function should return true if...如果您的严格标准是 function 应该返回 true 如果...

  • The types are identical类型相同
  • One type is the parent (immediate or otherwise) of the other一种类型是另一种类型的父级(直接或其他)
  • The two types have the same immediate parent这两种类型具有相同的直接父级

You could use你可以使用

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
}

You can also use the "IS" keyword, if you expect the two object instances to be of a certain type.如果您希望两个 object 实例属于某种类型,您也可以使用“IS”关键字。 This will also work for comparing sub-classes to parent classes and also classes that implement interfaces and so forth.这也适用于将子类与父类以及实现接口的类等进行比较。 This will not work for types of type Type though.不过,这不适用于 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

I tried out the following with a hierarchy using both interfaces and concrete classes.我使用接口和具体类尝试了以下层次结构。 It walks up the base class chain for one of the types till it reaches "object" at which we check if the current destination type is assignable to the source type.它遍历其中一种类型的基本 class 链,直到它到达“对象”,在此我们检查当前目标类型是否可分配给源类型。 We also check if the types have a common interface.我们还检查类型是否具有公共接口。 if they do then they 'AreSame'如果他们这样做,那么他们'AreSame'

Hope this helps.希望这可以帮助。

 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());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM