59 votes

Comparaison des types d'objets en C#

Comment puis-je 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) {

}

87voto

John Feminella Points 116878

Dites a et b sont les deux objets. Si vous voulez voir si a et b se situent dans la même hiérarchie d'héritage, alors utilisez la fonction 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 voulez vérifier si l'un est une classe de base de l'autre, essayez alors Type.IsSubclassOf .

Si vous connaissez la classe de base spécifique, il vous suffit d'utiliser l'attribut is mot-clé :

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

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

32voto

Adam Robinson Points 88472

Cette idée pose toutefois un petit problème, car tous les objets (et, en fait, tous les types) ont une classe de base commune, Object. Ce que vous devez définir, c'est jusqu'où vous voulez remonter dans la chaîne d'héritage (soit ils sont identiques, soit ils ont le même parent immédiat, soit l'un est le parent immédiat de l'autre, etc. IsAssignableFrom est utile pour déterminer si les types sont compatibles entre eux, mais ne permet pas de savoir s'ils ont le même parent (si c'est ce que vous recherchez).

Si votre critère strict est que la fonction doit retourner vrai si...

  • Les types sont identiques
  • Un type est le parent (immédiat ou non) d'un autre type.
  • 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
}

13voto

James Points 7234

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 mères, ainsi que les classes qui implémentent des interfaces, etc. 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

2voto

Abhijeet Patel Points 2116

J'ai essayé ce qui suit avec une hiérarchie utilisant à la fois des interfaces et des classes concrètes. Il remonte la chaîne des classes de base pour l'un des types jusqu'à ce qu'il atteigne "object", où nous vérifions si le type de destination actuel est assignable au type source. Nous vérifions également si les types ont une interface commune. Si c'est le cas, ils sont 'AreSame'.

J'espère que cela vous aidera.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X