C# 对象类型比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/708205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 14:13:48  来源:igfitidea点击:

C# Object Type Comparison

c#types

提问by B Z

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.

我想知道两个对象是否属于同一类型或来自同一个基类。

Any help is appreciated.

任何帮助表示赞赏。

e.g.

例如

private bool AreSame(Type a, Type b) {

}

采纳答案by John Feminella

Say aand bare the two objects. If you want to see if aand bare in the same inheritance hierarchy, then use Type.IsAssignableFrom:

ab是两个对象。如果您想查看ab是否在同一继承层次结构中,请使用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.

如果要检查一个是否是另一个的基类,请尝试Type.IsSubclassOf.

If you know the specific base class, then just use the iskeyword:

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

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

Otherwise, you'll have to walk the inheritance hierarchy directly.

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

回答by James

You can also use the "IS" keyword, if you expect the two object instances to be of a certain type. 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.

如果您希望两个对象实例属于某种类型,您也可以使用“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

回答by Adam Robinson

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. 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. IsAssignableFromis 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).

但是,这个想法有点问题,因为每个对象(实际上,每个类型)都有一个公共基类 Object。您需要定义的是您想要在继承链上走多远(无论它们是相同的还是具有相同的直接父代,或者一个是另一个的直接父代,等等)并执行您的那样检查。IsAssignableFrom用于确定类型是否彼此兼容,但不会完全确定它们是否具有相同的父级(如果这是您所追求的)。

If your strict criteria is that the function should return true if...

如果您的严格标准是该函数应返回 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
}

回答by Abhijeet Patel

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. We also check if the types have a common interface. if they do then they '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());
    }
}