इंटरफ़ेस लागू करने वाले सभी प्रकार प्राप्त करना


553

प्रतिबिंब का उपयोग करते हुए, मैं सभी प्रकार कैसे प्राप्त कर सकता हूं जो कम से कम कोड के साथ C # 3.0 / .NET 3.5 के साथ एक इंटरफ़ेस लागू करते हैं, और पुनरावृत्तियों को कम करते हैं?

यह वही है जो मैं फिर से लिखना चाहता हूं:

foreach (Type t in this.GetType().Assembly.GetTypes())
    if (t is IMyInterface)
        ; //do stuff

1
क्या उदाहरण कोड काम करता है? अगर आपकी हालत खराब है
सम्राट ओरियोनी

3
यदि ऊपर दिए गए कोड में कथन हमेशा गलत होगा क्योंकि आप परीक्षण कर रहे हैं यदि प्रकार वर्ग (t) का एक उदाहरण आपके इंटरफ़ेस को लागू करता है जो तब तक नहीं होगा जब तक कि टाइप IMyInterface (जिस स्थिति में यह हमेशा सही होगा) का वारिस नहीं होता है।
लिआजी

जवाबों:


806

मेरा यह c # 3.0 में होगा :)

var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(p => type.IsAssignableFrom(p));

मूल रूप से, पुनरावृत्तियों की कम से कम राशि हमेशा रहेगी:

loop assemblies  
 loop types  
  see if implemented.

194
ध्यान दें कि सूची में इंटरफ़ेस भी शामिल हो सकता है। .Where(p => type.IsAssignableFrom(p) && !p.IsInterface);इसे (या p.IsClass) फ़िल्टर करने के लिए अंतिम पंक्ति बदलें ।
jtpereyda 21

39
नोट: यह उत्तर गलत है! यह "असाइनमेंट संगतता" की जाँच करता है कि क्या इंटरफ़ेस लागू नहीं है। उदाहरण के लिए List<string>लागू नहीं होता है, IEnumerable<object>लेकिन यह विधि .Net 4.0 कोविरेंस के कारण सही हो जाएगी जो वास्तव में गलत है। सही उत्तर यहाँ है
श्रीराम सक्थिवेल

20
@ श्रीरामसक्तीवेल पहले बंद, सामान्य मूल्य निर्दिष्ट नहीं थे। दूसरा, यह प्रश्न सहसंयोजकता से पहले का है। तीसरा, आप यह धारणा बनाते हैं कि सहसंयोजक वापसी कुछ ऐसा नहीं है जो वे चाहते हैं।
डैरेन कोप्प

24
आप बिल्कुल सही डेरेन हैं, मुझे पता है कि यह एक पुराना धागा है, मैंने अभी अपनी टिप्पणी भविष्य के उपयोगकर्ताओं के लिए इस तरह की समस्या से अवगत कराने के लिए दर्ज की है। आपको नाराज करने के लिए नहीं। और जैसा कि प्रश्न शीर्षक कहता है कि यदि ओपी उन सभी प्रकारों को प्राप्त करने के लिए कह रहा है जो एक इंटरफ़ेस लागू करते हैं तो यह कोड ऐसा नहीं कर रहा है। लेकिन लगभग सभी मामलों में यह काम करता है , इसमें कोई संदेह नहीं है। जैसा कि मैंने कहा, कोने के मामले भी हैं। बस इसके प्रति जागरूक होना;
श्रीराम सक्तीवेल

9
यह भी सुनिश्चित करने की आवश्यकता होगी कि कक्षा सार नहीं है =>.Where(p => type.IsAssignableFrom(p) && p.IsClass && !p.IsAbstract
जोन्सोपोलिस

66

इसने मेरे लिए काम किया। हालांकि यह देखता है कि कक्षाएं और चेक देखने के लिए कि क्या वे myInterface से निकले हैं

 foreach (Type mytype in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
                 .Where(mytype => mytype .GetInterfaces().Contains(typeof(myInterface)))) {
    //do stuff
 }

5
आप मान रहे हैं कि विधानसभा मुख्य निष्पादन योग्य है। अतिरिक्त प्रोजेक्ट नहीं। आप भी अनावश्यक रूप से पुनरावृत्ति कर रहे हैं, हालांकि पुनरावृत्तियों का एक गुच्छा। यह बेहतर है कि फ्रेमवर्क भारी उठाने का काम करे। फिर नीचे पाए जाने पर छान लें। यदि प्रासंगिक है, तो कृपया अपना उत्तर अपडेट करें। सूची <टी> तर्क शामिल करें। var classTypesImplementingInterface = AppDomain.CurrentDomain.GetAsslies ()। SelectMany (x => x.GetTypes ())। जहाँ (mytype>> typeof (myInterface) .IsAssignableFrom (mytype) और mytype। mytype। mytype) है। )); foreach (मदों में var आइटम) Console.Log (item.Name);
तमसुराजॉय

58

IFoo इंटरफ़ेस को लागू करने वाली विधानसभा के सभी प्रकार खोजने के लिए:

var results = from type in someAssembly.GetTypes()
              where typeof(IFoo).IsAssignableFrom(type)
              select type;

ध्यान दें कि रयान रिनाल्डी का सुझाव गलत था। यह 0 प्रकारों को लौटाएगा। आप लिख नहीं सकते

where type is IFoo

क्योंकि टाइप एक System.Type उदाहरण है, और IFoo प्रकार का नहीं होगा। इसके बजाय, आप यह देखने के लिए जांचें कि क्या IFoo प्रकार से असाइन करने योग्य है। इससे आपके अपेक्षित परिणाम प्राप्त होंगे।

इसके अलावा, एडम राइट का सुझाव, जो वर्तमान में उत्तर के रूप में चिह्नित है, गलत भी है और इसी कारण से भी। रनटाइम के दौरान, आपको 0 प्रकार दिखाई देंगे, क्योंकि सभी System.Type इंस्टेंसेस IFU कार्यान्वयनकर्ता नहीं थे।


58

मैं इसकी सराहना करता हूं यह एक बहुत पुराना सवाल है, लेकिन मुझे लगा कि मैं भविष्य के उपयोगकर्ताओं के लिए एक और उत्तर जोड़ूंगा क्योंकि सभी उत्तर किसी न किसी रूप का उपयोग करते हैं Assembly.GetTypes

Whilst GetTypes () वास्तव में सभी प्रकारों को वापस करेगा, इसका मतलब यह नहीं है कि आप उन्हें सक्रिय कर सकते हैं और इस प्रकार संभवतः फेंक सकते हैं ReflectionTypeLoadException

एक प्रकार को सक्रिय नहीं करने के लिए एक क्लासिक उदाहरण तब होगा जब प्रकार लौटाया गया derivedहो, baseलेकिन baseउस विधानसभा से अलग विधानसभा में परिभाषित किया गया हो derived, जिसे कॉलिंग असेंबली संदर्भित नहीं करती है।

तो हम कहते हैं:

Class A // in AssemblyA
Class B : Class A, IMyInterface // in AssemblyB
Class C // in AssemblyC which references AssemblyB but not AssemblyA

में तो ClassCहै, जिसमें है AssemblyCहम तो स्वीकार किए जाते हैं जवाब के अनुसार कुछ करना:

var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(p => type.IsAssignableFrom(p));

तो यह एक फेंक देंगे ReflectionTypeLoadException

इसका कारण यह है के लिए एक संदर्भ के बिना है AssemblyA में AssemblyCआप के लिए सक्षम नहीं होगा:

var bType = typeof(ClassB);
var bClass = (ClassB)Activator.CreateInstance(bType);

दूसरे शब्दों ClassBमें, लोड करने योग्य नहीं है जो कुछ ऐसा है जो गेटटाइप्स कॉल को चेक करता है और फेंकता है।

तो लोड करने योग्य प्रकारों के लिए निर्धारित परिणाम को सुरक्षित रूप से अर्हता प्राप्त करने के लिए इस फिल हैकेड लेख के अनुसार एक विधानसभा और जॉन स्कीट कोड में सभी प्रकार प्राप्त करें, इसके बजाय आप कुछ ऐसा करेंगे:

public static class TypeLoaderExtensions {
    public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly) {
        if (assembly == null) throw new ArgumentNullException("assembly");
        try {
            return assembly.GetTypes();
        } catch (ReflectionTypeLoadException e) {
            return e.Types.Where(t => t != null);
        }
    }
}

और तब:

private IEnumerable<Type> GetTypesWithInterface(Assembly asm) {
    var it = typeof (IMyInterface);
    return asm.GetLoadableTypes().Where(it.IsAssignableFrom).ToList();
}

3
इससे मुझे एक अजीब अजीब समस्या से निपटने में मदद मिली, जहां मेरे टेस्ट प्रोजेक्ट में गेटपाइप विफल हो जाएगा और केवल हमारे सीआई-पर्यावरण में होगा। GetLoadableTypes इस समाधान के लिए एक समाधान था। त्रुटि स्थानीय वातावरण में प्रतिलिपि प्रस्तुत करने योग्य नहीं होगी और यह थी: System.Reflection.ReflectionTypeLoadException: अनुरोध किए गए प्रकारों में से एक या अधिक लोड करने में असमर्थ। अधिक जानकारी के लिए लोडरएक्सेप्शंस संपत्ति पुनर्प्राप्त करें। अधिक विशेष रूप से यह शिकायत थी कि एक प्रकार था जो एक ठोस कार्यान्वयन नहीं था और यह इकाई परीक्षण परियोजना में हुआ था। इसके लिए धन्यवाद!
लारी तुओमिस्टो

2
इस उत्तर को समाधान के रूप में चिह्नित किया जाना चाहिए, इसने मेरी गांड को आज बचा लिया, क्योंकि @Lari Tuomisto ने कहा, स्थानीय env पर हम इसी तरह की त्रुटि को फिर से उत्पाद नहीं कर सकते हैं
लाइटनिंग 3

3
मामले में यह किसी और की मदद करता है: इस समाधान ने मेरे लिए काम किया, लेकिन मुझे सूची से इंटरफ़ेस प्रकार को हटाने के लिए इसे संशोधित करना पड़ा। मैं CreateInstanceउन सभी के लिए सक्रिय करना चाहता था , और एक अपवाद फेंक दिया गया था जब यह वास्तविक इंटरफ़ेस बनाने की कोशिश कर रहा था (जो मुझे थोड़ी देर के लिए उलझन में था जब मुझे लगा कि वास्तविक इंटरफ़ेस इस समाधान में रास्ते से बाहर था)। इसलिए मैंने कोड को बदल दिया GetLoadableTypes(assembly).Where(interfaceType.IsAssignableFrom).Where(t => !(t.Equals(interfaceType))).ToList();
जेवियर Peña

21

अन्य उत्तर यहाँ उपयोग करते हैं IsAssignableFrom। आप यहां बताए FindInterfacesगए Systemनामों से भी उपयोग कर सकते हैं

यहां एक उदाहरण है जो वर्तमान में असेंबली के फ़ोल्डर में सभी असेंबली की जांच करता है, एक निश्चित इंटरफ़ेस को लागू करने वाली कक्षाओं की तलाश में (LINQ से बचने के लिए)।

static void Main() {
    const string qualifiedInterfaceName = "Interfaces.IMyInterface";
    var interfaceFilter = new TypeFilter(InterfaceFilter);
    var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    var di = new DirectoryInfo(path);
    foreach (var file in di.GetFiles("*.dll")) {
        try {
            var nextAssembly = Assembly.ReflectionOnlyLoadFrom(file.FullName);
            foreach (var type in nextAssembly.GetTypes()) {
                var myInterfaces = type.FindInterfaces(interfaceFilter, qualifiedInterfaceName);
                if (myInterfaces.Length > 0) {
                    // This class implements the interface
                }
            }
        } catch (BadImageFormatException) {
            // Not a .net assembly  - ignore
        }
    }
}

public static bool InterfaceFilter(Type typeObj, Object criteriaObj) {
    return typeObj.ToString() == criteriaObj.ToString();
}

यदि आप एक से अधिक मिलान करना चाहते हैं, तो आप इंटरफेस की एक सूची सेट कर सकते हैं।


यह एक स्ट्रिंग इंटरफ़ेस नाम की तलाश करता है जो कि मैं देख रहा था।
संतरी

एक अलग डोमेन में असेंबली लोड करते समय काम करता है, क्योंकि प्रकार को एक स्ट्रिंग में क्रमबद्ध किया जाना है। बहुत अच्छा!
TamusJRoyce

मुझे मिलता है: विधानसभा 'System.Core, संस्करण = 4.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = b77a5c561934e089' पर निर्भरता को हल नहीं किया जा सकता क्योंकि यह पूर्व लोड नहीं किया गया है। ReflectionOnly API का उपयोग करते समय, निर्भर असेंबलियों को पूर्व-लोड या मांग पर ReflectionOnlyAssemblyResolve इवेंट के माध्यम से लोड किया जाना चाहिए।
bkwdesign

18

सभी भरी हुई विधानसभाओं के माध्यम से लूप, उनके सभी प्रकारों के माध्यम से लूप, और अगर वे इंटरफ़ेस को लागू करते हैं, तो जांचें।

कुछ इस तरह:

Type ti = typeof(IYourInterface);
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) {
    foreach (Type t in asm.GetTypes()) {
        if (ti.IsAssignableFrom(t)) {
            // here's your type in t
        }
    }
}

8

इसने मेरे लिए काम किया (यदि आप चाहें तो लुकअप में सिस्टम प्रकारों को बाहर कर सकते हैं):

Type lookupType = typeof (IMenuItem);
IEnumerable<Type> lookupTypes = GetType().Assembly.GetTypes().Where(
        t => lookupType.IsAssignableFrom(t) && !t.IsInterface); 

5

संपादित करें: मैंने सिर्फ यह स्पष्ट करने के लिए संपादन देखा है कि मूल प्रश्न पुनरावृत्तियों / कोड की कमी के लिए था और यह सब एक अभ्यास के रूप में अच्छी तरह से और अच्छा है, लेकिन वास्तविक दुनिया की स्थितियों में आप सबसे तेज़ कार्यान्वयन चाहते हैं, चाहे अंतर्निहित LINQ कितना अच्छा लगता है।

यहाँ लोड किए गए प्रकारों के माध्यम से पुनरावृत्ति के लिए मेरा उपयोग तरीका है यह नियमित कक्षाओं के साथ-साथ इंटरफेस को भी संभालता है, और यदि आप अपने स्वयं के / तीसरे पक्ष के कोडबेस में कार्यान्वयन की तलाश कर रहे हैं, तो बहिष्कृत सिस्टम विकल्प बहिष्कृत करते हैं।

public static List<Type> GetSubclassesOf(this Type type, bool excludeSystemTypes) {
    List<Type> list = new List<Type>();
    IEnumerator enumerator = Thread.GetDomain().GetAssemblies().GetEnumerator();
    while (enumerator.MoveNext()) {
        try {
            Type[] types = ((Assembly) enumerator.Current).GetTypes();
            if (!excludeSystemTypes || (excludeSystemTypes && !((Assembly) enumerator.Current).FullName.StartsWith("System."))) {
                IEnumerator enumerator2 = types.GetEnumerator();
                while (enumerator2.MoveNext()) {
                    Type current = (Type) enumerator2.Current;
                    if (type.IsInterface) {
                        if (current.GetInterface(type.FullName) != null) {
                            list.Add(current);
                        }
                    } else if (current.IsSubclassOf(type)) {
                        list.Add(current);
                    }
                }
            }
        } catch {
        }
    }
    return list;
}

यह सुंदर नहीं है, मैं मानता हूँ।


2
Enumerators IDis प्रयोज्य को कार्यान्वित करते हैं जो एक कोशिश / अंत में निपटाया नहीं जा रहा है। फोरच या लाइनक का उपयोग करना बेहतर है।
TamusJRoyce

आप excludeSystemTypesएक में दो बार परीक्षण क्यों कर रहे हैं if?
नेटमैज

4

अन्य उत्तर जेनेरिक इंटरफ़ेस के साथ काम नहीं कर रहे थे ।

यह एक, बस टाइपोफ (ISomeInterface) टाइपो (टी) द्वारा प्रतिस्थापित करता है।

List<string> types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())
            .Where(x => typeof(ISomeInterface).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract)
            .Select(x => x.Name).ToList();

के साथ

AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())

हमें सभी विधानसभाएं मिलती हैं

!x.IsInterface && !x.IsAbstract

इंटरफेस और अमूर्त लोगों को बाहर करने के लिए प्रयोग किया जाता है और

.Select(x => x.Name).ToList();

उन्हें एक सूची में रखना है।


कृपया बताएं कि आपका समाधान कैसे काम करता है और अन्य सभी उत्तरों से बेहतर क्यों है।
लुकास कोफर

यह बेहतर या कम नहीं है, अन्य जवाब मेरे काम नहीं आए और मैंने इसे साझा करने की जहमत उठाई।
एंटोनिन गेवल

मेरी टिप्पणी केवल आपके उत्तर के कोड-ओनली होने के बारे में थी, इसलिए मैंने आपसे कुछ स्पष्टीकरण जोड़ने को कहा।
लुकास कोफर

2

कोई आसान तरीका नहीं है (प्रदर्शन के मामले में) वह करने के लिए जो आप करना चाहते हैं।

परावर्तन मुख्य रूप से असेंबली और प्रकारों के साथ काम करता है इसलिए आपको सभी प्रकार की असेंबली प्राप्त करनी होगी और उन्हें सही इंटरफ़ेस के लिए क्वेरी करनी होगी। यहाँ एक उदाहरण है:

Assembly asm = Assembly.Load("MyAssembly");
Type[] types = asm.GetTypes();
Type[] result = types.where(x => x.GetInterface("IMyInterface") != null);

आपको विधानसभा MyAssembly में IMyInterface को लागू करने वाले सभी प्रकार मिलेंगे


2

विधानसभा स्थान चुनते समय और भी बेहतर। अधिकांश विधानसभाओं को फ़िल्टर करें यदि आप जानते हैं कि आपके सभी कार्यान्वित किए गए इंटरफेस एक ही विधानसभा के भीतर हैं।

// We get the assembly through the base class
var baseAssembly = typeof(baseClass).GetTypeInfo().Assembly;

// we filter the defined classes according to the interfaces they implement
var typeList = baseAssembly.DefinedTypes.Where(type => type.ImplementedInterfaces.Any(inter => inter == typeof(IMyInterface))).ToList();

बाय बिलजिन



1

कई मान्य उत्तर पहले से ही हैं, लेकिन मैं विभिन्न प्रकारों को प्रदर्शित करने के लिए एक प्रकार के विस्तार और इकाई परीक्षणों की सूची के रूप में एथेर कार्यान्वयन को जोड़ना चाहूंगा:

public static class TypeExtensions
{
    public static IEnumerable<Type> GetAllTypes(this Type type)
    {
        var typeInfo = type.GetTypeInfo();
        var allTypes = GetAllImplementedTypes(type).Concat(typeInfo.ImplementedInterfaces);
        return allTypes;
    }

    private static IEnumerable<Type> GetAllImplementedTypes(Type type)
    {
        yield return type;
        var typeInfo = type.GetTypeInfo();
        var baseType = typeInfo.BaseType;
        if (baseType != null)
        {
            foreach (var foundType in GetAllImplementedTypes(baseType))
            {
                yield return foundType;
            }
        }
    }
}

यह एल्गोरिथ्म निम्नलिखित परिदृश्यों का समर्थन करता है:

public static class GetAllTypesTests
{
    public class Given_A_Sample_Standalone_Class_Type_When_Getting_All_Types
        : Given_When_Then_Test
    {
        private Type _sut;
        private IEnumerable<Type> _expectedTypes;
        private IEnumerable<Type> _result;

        protected override void Given()
        {
            _sut = typeof(SampleStandalone);

            _expectedTypes =
                new List<Type>
                {
                    typeof(SampleStandalone),
                    typeof(object)
                };
        }

        protected override void When()
        {
            _result = _sut.GetAllTypes();
        }

        [Fact]
        public void Then_It_Should_Return_The_Right_Type()
        {
            _result.Should().BeEquivalentTo(_expectedTypes);
        }
    }

    public class Given_A_Sample_Abstract_Base_Class_Type_When_Getting_All_Types
        : Given_When_Then_Test
    {
        private Type _sut;
        private IEnumerable<Type> _expectedTypes;
        private IEnumerable<Type> _result;

        protected override void Given()
        {
            _sut = typeof(SampleBase);

            _expectedTypes =
                new List<Type>
                {
                    typeof(SampleBase),
                    typeof(object)
                };
        }

        protected override void When()
        {
            _result = _sut.GetAllTypes();
        }

        [Fact]
        public void Then_It_Should_Return_The_Right_Type()
        {
            _result.Should().BeEquivalentTo(_expectedTypes);
        }
    }

    public class Given_A_Sample_Child_Class_Type_When_Getting_All_Types
        : Given_When_Then_Test
    {
        private Type _sut;
        private IEnumerable<Type> _expectedTypes;
        private IEnumerable<Type> _result;

        protected override void Given()
        {
            _sut = typeof(SampleChild);

            _expectedTypes =
                new List<Type>
                {
                    typeof(SampleChild),
                    typeof(SampleBase),
                    typeof(object)
                };
        }

        protected override void When()
        {
            _result = _sut.GetAllTypes();
        }

        [Fact]
        public void Then_It_Should_Return_The_Right_Type()
        {
            _result.Should().BeEquivalentTo(_expectedTypes);
        }
    }

    public class Given_A_Sample_Base_Interface_Type_When_Getting_All_Types
        : Given_When_Then_Test
    {
        private Type _sut;
        private IEnumerable<Type> _expectedTypes;
        private IEnumerable<Type> _result;

        protected override void Given()
        {
            _sut = typeof(ISampleBase);

            _expectedTypes =
                new List<Type>
                {
                    typeof(ISampleBase)
                };
        }

        protected override void When()
        {
            _result = _sut.GetAllTypes();
        }

        [Fact]
        public void Then_It_Should_Return_The_Right_Type()
        {
            _result.Should().BeEquivalentTo(_expectedTypes);
        }
    }

    public class Given_A_Sample_Child_Interface_Type_When_Getting_All_Types
        : Given_When_Then_Test
    {
        private Type _sut;
        private IEnumerable<Type> _expectedTypes;
        private IEnumerable<Type> _result;

        protected override void Given()
        {
            _sut = typeof(ISampleChild);

            _expectedTypes =
                new List<Type>
                {
                    typeof(ISampleBase),
                    typeof(ISampleChild)
                };
        }

        protected override void When()
        {
            _result = _sut.GetAllTypes();
        }

        [Fact]
        public void Then_It_Should_Return_The_Right_Type()
        {
            _result.Should().BeEquivalentTo(_expectedTypes);
        }
    }

    public class Given_A_Sample_Implementation_Class_Type_When_Getting_All_Types
        : Given_When_Then_Test
    {
        private Type _sut;
        private IEnumerable<Type> _expectedTypes;
        private IEnumerable<Type> _result;

        protected override void Given()
        {
            _sut = typeof(SampleImplementation);

            _expectedTypes =
                new List<Type>
                {
                    typeof(SampleImplementation),
                    typeof(SampleChild),
                    typeof(SampleBase),
                    typeof(ISampleChild),
                    typeof(ISampleBase),
                    typeof(object)
                };
        }

        protected override void When()
        {
            _result = _sut.GetAllTypes();
        }

        [Fact]
        public void Then_It_Should_Return_The_Right_Type()
        {
            _result.Should().BeEquivalentTo(_expectedTypes);
        }
    }

    public class Given_A_Sample_Interface_Instance_Type_When_Getting_All_Types
        : Given_When_Then_Test
    {
        private Type _sut;
        private IEnumerable<Type> _expectedTypes;
        private IEnumerable<Type> _result;

        class Foo : ISampleChild { }

        protected override void Given()
        {
            var foo = new Foo();
            _sut = foo.GetType();

            _expectedTypes =
                new List<Type>
                {
                    typeof(Foo),
                    typeof(ISampleChild),
                    typeof(ISampleBase),
                    typeof(object)
                };
        }

        protected override void When()
        {
            _result = _sut.GetAllTypes();
        }

        [Fact]
        public void Then_It_Should_Return_The_Right_Type()
        {
            _result.Should().BeEquivalentTo(_expectedTypes);
        }
    }

    sealed class SampleStandalone { }
    abstract class SampleBase { }
    class SampleChild : SampleBase { }
    interface ISampleBase { }
    interface ISampleChild : ISampleBase { }
    class SampleImplementation : SampleChild, ISampleChild { }
}

0
   public IList<T> GetClassByType<T>()
   {
        return AppDomain.CurrentDomain.GetAssemblies()
                          .SelectMany(s => s.GetTypes())
                          .ToList(p => typeof(T)
                          .IsAssignableFrom(p) && !p.IsAbstract && !p.IsInterface)
                          .SelectList(c => (T)Activator.CreateInstance(c));
   }

0

मुझे लिनक-कोड में अपवाद मिला, इसलिए मैं इसे इस तरह से करता हूं (बिना जटिल विस्तार के):

private static IList<Type> loadAllImplementingTypes(Type[] interfaces)
{
    IList<Type> implementingTypes = new List<Type>();

    // find all types
    foreach (var interfaceType in interfaces)
        foreach (var currentAsm in AppDomain.CurrentDomain.GetAssemblies())
            try
            {
                foreach (var currentType in currentAsm.GetTypes())
                    if (interfaceType.IsAssignableFrom(currentType) && currentType.IsClass && !currentType.IsAbstract)
                        implementingTypes.Add(currentType);
            }
            catch { }

    return implementingTypes;
}

-3

सूची प्राप्त करने के लिए आप कुछ LINQ का उपयोग कर सकते हैं:

var types = from type in this.GetType().Assembly.GetTypes()
            where type is ISomeInterface
            select type;

लेकिन वास्तव में, क्या यह अधिक पठनीय है?


6
यह अधिक पठनीय हो सकता है, अगर यह काम करता है। दुर्भाग्य से, आपका क्लॉज़ यह देखने के लिए जाँच कर रहा है कि क्या System.Type वर्ग का उदाहरण ISomeInterface को लागू करता है, जो कभी भी सत्य नहीं होगा, जब तक कि ISomeInterface वास्तव में IReflect या ICustomAttributeProvider नहीं है, जिस स्थिति में यह हमेशा सत्य होगा।
जोएल म्यूलर

ऊपर दिए गए कार्ल नायक के जवाब में क्लॉज को सही करने का जवाब है: IsAssignableFrom। एक उत्तर के लिए आसान गलती।
TamusJRoyce
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.