2011-06-21 36 views
6

देने के बिना जेनेरिक से सभी कक्षाओं को सबक्लासिंग करने के लिए प्रतिबिंब का उपयोग कैसे कर सकता हूं, मैं जेनिक्स का उपयोग करने वाले वर्ग के उप-वर्गों के सभी वर्गों को वापस करने के लिए प्रतिबिंब का उपयोग करके एक विधि लिखने की कोशिश कर रहा हूं, बिना सीमित किए सामान्य प्रकार। तो उदाहरण के लिए, ईएफ में मैं सभी मैपिंग कक्षाएं खोजना चाहता हूं।मैं सामान्य जेनेरिक प्रकार

public class clientMap : EntityTypeConfiguration<Client> {} 

मैं विशेष रूप से टी के रूप में Client निर्दिष्ट किए बिना मेरी विधानसभा EntityTypeConfiguration<T> की की एक उपवर्ग है कि, में सभी वर्गों को खोजने के लिए चाहते हैं: कक्षाएं सेटअप की तरह हैं। मैं बिना किसी हार्डकोडिंग के अपने आवेदन में सभी कक्षाओं के लिए इकाई प्रकार कॉन्फ़िगरेशन वापस करना चाहता हूं।

जेनरिक के बिना मैं असेंबली के प्रकारों के माध्यम से लूप करता हूं, जांच करें कि type.IsSubclassOf(typeof(BaseClass)), हालांकि मुझे यकीन नहीं है कि जेनेरिक से निपटने के दौरान यह कैसे करना है।

+2

डुप्लिकेट होना चाहिए ? http://stackoverflow.com/questions/457676/c-reflection-check-if-a-class-is-derived-from-a-generic-class –

+0

आह ने यह नहीं देखा, धन्यवाद – KallDrexx

उत्तर

10

मुझे विश्वास है कि आप कुछ इस तरह हैं:

static class TypeExtensions { 
    public static bool IsDerivedFromOpenGenericType(
     this Type type, 
     Type openGenericType 
    ) { 
     Contract.Requires(type != null); 
     Contract.Requires(openGenericType != null); 
     Contract.Requires(openGenericType.IsGenericTypeDefinition); 
     return type.GetTypeHierarchy() 
        .Where(t => t.IsGenericType) 
        .Select(t => t.GetGenericTypeDefinition()) 
        .Any(t => openGenericType.Equals(t)); 
    } 

    public static IEnumerable<Type> GetTypeHierarchy(this Type type) { 
     Contract.Requires(type != null); 
     Type currentType = type; 
     while (currentType != null) { 
      yield return currentType; 
      currentType = currentType.BaseType; 
     } 
    } 
} 

इन परीक्षणों से पारित:

class Foo<T> { } 
class Bar : Foo<int> { } 
class FooBar : Bar { } 

[Fact] 
public void BarIsDerivedFromOpenGenericFoo() { 
    Assert.True(typeof(Bar).IsDerivedFromOpenGenericType(typeof(Foo<>))); 
} 

[Fact] 
public void FooBarIsDerivedFromOpenGenericFoo() { 
    Assert.True(typeof(FooBar).IsDerivedFromOpenGenericType(typeof(Foo<>))); 
} 

[Fact] 
public void StringIsNotDerivedFromOpenGenericFoo() { 
    Assert.False(typeof(string).IsDerivedFromOpenGenericType(typeof(Foo<>))); 
} 
+0

'openGenericType' क्या होना चाहिए वास्तविक कोड में हो? 'EntityType कॉन्फ़िगरेशन <>' या ब्रैकेट में कुछ होना चाहिए? – KallDrexx

+0

आपके मामले के लिए, 'टाइपऑफ (EntityType कॉन्फ़िगरेशन <>) '। कोड और परीक्षण नोट करें यह स्पष्ट करें। – jason

+1

शानदार काम करता है :) – KallDrexx

0

जहाँ तक मैं अपने मामले समझा निम्नलिखित पर्याप्त

type.BaseType != null && 
type.BaseType.MetadataToken == typeof(EntityTypeConfiguration<>).MetadataToken 
संबंधित मुद्दे