web-dev-qa-db-fra.com

Comparaison des types d'objets C #

Comment comparer les types de deux objets déclarés comme type.

Je veux savoir si deux objets sont du même type ou de la même classe de base.

Toute aide est appréciée.

par exemple.

private bool AreSame(Type a, Type b) {

}
58
B Z

Disons que a et b sont les deux objets. Si vous voulez voir si a et b sont dans la même hiérarchie d'héritage, utilisez 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
}

Si vous souhaitez vérifier si l'une est une classe de base de l'autre, essayez Type.IsSubclassOf.

Si vous connaissez la classe de base spécifique, utilisez simplement le mot clé is:

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

Sinon, vous devrez parcourir directement la hiérarchie d'héritage.

86
John Feminella

Il y a cependant un petit problème avec cette idée, car chaque objet (et, en fait, chaque type) A une classe de base commune, Object. Ce que vous devez définir, c'est jusqu'où vous voulez aller dans la chaîne d'héritage (que ce soit le même ou qu'ils aient le même parent immédiat, ou que l'un soit le parent immédiat de l'autre, etc.) et faites votre vérifie de cette façon. IsAssignableFrom est utile pour déterminer si les types sont compatibles les uns avec les autres, mais n'établiront pas complètement s'ils ont le même parent (si c'est ce que vous recherchez).

Si vos critères stricts sont que la fonction doit retourner true si ...

  • Les types sont identiques
  • Un type est le parent (immédiat ou non) de l'autre
  • Les deux types ont le même parent immédiat

Vous pourriez utiliser

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
}
31
Adam Robinson

Vous pouvez également utiliser le mot clé "IS", si vous vous attendez à ce que les deux instances d'objet soient d'un certain type. Cela fonctionnera également pour comparer les sous-classes aux classes parentes et également aux classes qui implémentent des interfaces et ainsi de suite. Cependant, cela ne fonctionnera pas pour les types de type 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
13
James

J'ai essayé ce qui suit avec une hiérarchie utilisant à la fois des interfaces et des classes concrètes. Il parcourt la chaîne de classe de base pour l'un des types jusqu'à ce qu'il atteigne "objet" auquel nous vérifions si le type de destination actuel est attribuable au type source. Nous vérifions également si les types ont une interface commune. s'ils le font, alors ils sont "identiques"

J'espère que cela t'aides.

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