2009-04-02 27 views
56

Tür olarak bildirilen iki nesnenin türlerini nasıl karşılaştırabilirim.C# Nesne Türü Karşılaştırma

İki nesnenin aynı türde mi yoksa aynı temel sınıftan mı olduğunu bilmek istiyorum.

Herhangi bir yardım için teşekkür ederiz.

örn. İki nesne örnekleri belirli türde olmasını bekliyoruz eğer

private bool AreSame(Type a, Type b) { 

} 

cevap

84

ki a ve b iki nesneleridir. Eğer a ve b aynı kalıtım hiyerarşisinde olup olmadığını görmek istiyorsanız, o zaman Type.IsAssignableFrom kullanın: Eğer bir başka bir taban sınıfı olup olmadığını kontrol etmek istiyorsanız

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 
} 

ardından Type.IsSubclassOf deneyin. doğrudan miras hiyerarşisini yürümek gerekecek Aksi

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

: Belirli temel sınıf biliyorsanız

, o zaman sadece is anahtar kelime kullanın.

+0

+1 Bu kullanışlı fonksiyonun farkında değildim IsAssignableFrom, bunu aklımda tutmak zorundayım. – James

+0

Yansıma hiyerarşisinde oldukça yararlı şeyler var! Sadece üye listesine göz atmak ilginçtir - İhtiyacınız olanı bulabileceğiniz oldukça iyi bir şans. Yine de dokümanlar okuyun. Örneğin, t tipi bir jenerik tip param olsaydı ve bir kısıtlama ise, IsAssignableFrom doğru olur. –

+0

Sadece FYI, yine de, eğer iki sınıf aynı temel sınıfa sahipse, bu doğru olmaz. –

13

Ayrıca, "OLDUĞU" anahtar kelimesini kullanabilirsiniz. Bu, alt sınıfların üst sınıflara ve aynı zamanda arayüzleri uygulayan sınıflara ve benzerlerine karşılaştırılması için de çalışacaktır. Bu, Type tipi olsa da çalışmayacaktır.

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 
+0

Ne tür olduklarını bilmiyorum, sadece aynı veya aynı temel sınıftan olup olmadıklarını bilmem gerek. –

+1

Bu, yalnızca tür türlerinde çalışır, Tür tipi türler için değil. –

31

Bu fikirde bir sorun var, ancak her nesne (ve aslında her tür) DOES'in ortak bir temel sınıfı olan Object. Tanımlamanız gereken şey miras kalıtım zincirinin ne kadar uzağa gitmesidir (ister aynı mı, ister aynı anababaya sahip olsunlar, ister diğeri de diğeridir, vs.). Bu şekilde kontrol eder. IsAssignableFrom, türlerin birbiriyle uyumlu olup olmadığını belirlemek için kullanışlıdır, ancak aynı üst öğeye sahip olup olmadıklarını tam olarak belirleyemez (eğer öyleyse işte bu ise).

sizin sıkı kriterler ise

  • tip
  • Bir tip diğer
  • iki (Aksi derhal veya) üstüdür aynıdır ... fonksiyon true döndürür gerektiğidir tipleri

Sen

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 
} 
kullanabilirsiniz aynı ebeveyne sahip olmasını
+0

harika bir örnek ve açıklama. +1 –

+0

Kabul edilen bir cevabı paylaşmanın bir yolu olmasını diledim. Yine Thx. –

+0

@Adam: Her iki yaklaşımımızı birleştirmenin bir yolu olmadığını merak ediyorum. (1) System.Object (veya daha sınırlı türetilmiş tür) [başarısız] veya (2) bir eşleşme [veya] ulaşana kadar BaseType.GetType() yönteminin her ikisi de alınmasından kaynaklanan Türlerin bir listesini tutabilirsiniz. ] geçmektedir. –

2

Her iki arabirimi ve beton sınıflarını kullanarak bir hiyerarşi ile aşağıdakileri denedim. Geçerli hedef türünün kaynak türüne atanabildiğini kontrol ettiğimiz "nesne" ye ulaşana kadar, türlerden biri için temel sınıf zincirini yürür. Ayrıca türlerin ortak bir arayüz olup olmadığını kontrol ediyoruz. eğer yaparlarsa o zaman 'AreSame'

Bu yardımcı olur.

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

thx. +1 –