একটি ইন্টারফেস প্রয়োগ করে এমন সমস্ত ধরণের প্রাপ্তি


553

প্রতিবিম্ব ব্যবহার করে, কীভাবে আমি সমস্ত প্রকারগুলি পেতে পারি যা ন্যূনতম কোড সহ সি # 3.0 / .NET 3.5 এর সাথে একটি ইন্টারফেস কার্যকর করে এবং পুনরাবৃত্তিকে হ্রাস করে?

এটি আমি আবার লিখতে চাই:

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

1
উদাহরণ কোডটি কি কাজ করে? আমি যদি আপনার শর্তের সাথে মিথ্যা নেতিবাচক পেয়েছি।
সম্রাট ওরিওনি

3
উপরের কোডে যদি বিবৃতিটি সর্বদা মিথ্যা হবে কারণ আপনি পরীক্ষা করছেন যদি টাইপ শ্রেণির কোনও উদাহরণ আপনার ইন্টারফেসটি প্রয়োগ করে যা টাইপটি আইএমআইইন্টারফেসটি উত্তরাধিকার সূত্রে প্রাপ্ত না করে (যদি এটি সর্বদা সত্য হয়)।
লিয়াজি

উত্তর:


806

আমার এই সি # 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

39
দ্রষ্টব্য: এই উত্তরটি ভুল !, এই ইন্টারফেস প্রয়োগ করা হয় কিনা তা "অ্যাসাইনমেন্ট সামঞ্জস্যতা" পরীক্ষা করে। উদাহরণস্বরূপ List<string>বাস্তবায়ন হয় না IEnumerable<object>তবে এই পদ্ধতিটি প্রকৃতপক্ষে ভুল c সঠিক উত্তরটি এখানে রয়েছে
শ্রীরাম সাক্তিভেল

20
@ শ্রীরামশক্তিভেল প্রথমে বন্ধ, জেনেরিক মান নির্দিষ্ট করা হয়নি। দ্বিতীয়ত, এই প্রশ্নটি পূর্ব-তারিখের সম্প্রচার iance তৃতীয়, আপনি এই ধারণাটি তৈরি করেন যে সমবায় ফেরত তারা চান এমন কিছু নয়।
ড্যারেন কোপ্প

24
আপনি একদম ঠিক ডারেন, আমি জানি এটি একটি পুরানো থ্রেড, আমি ভবিষ্যতের ব্যবহারকারীদেরকে এই জাতীয় সমস্যা সম্পর্কে সচেতন করার জন্য কেবল আমার মন্তব্যটি নিবন্ধিত করেছি। আপনাকে অসন্তুষ্ট করার জন্য নয়। এবং যেমন প্রশ্নের শিরোনামে বলা হয়েছে যে ওপি যদি এমন সব ধরণের পাওয়ার জন্য জিজ্ঞাসা করে যা কোনও ইন্টারফেস কার্যকর করে এই কোডটি এটি করছে না। তবে এটি প্রায় সমস্ত ক্ষেত্রেই কাজ করে , সন্দেহ নেই। আমি যেমন বলেছি সেখানে কর্নার কেসগুলিও রয়েছে। এটি সম্পর্কে সচেতন হতে;
শ্রীরাম সাক্তিভেল

9
ক্লাসটি বিমূর্ত নয় তাও নিশ্চিত করতে হবে =>.Where(p => type.IsAssignableFrom(p) && p.IsClass && !p.IsAbstract
জোনেসোপলিস

66

এটি আমার পক্ষে কাজ করেছে। এটি লুপ করে যদিও ক্লাসগুলি পরীক্ষা করে এবং সেগুলি মাই ইন্টারফেস থেকে প্রাপ্ত কিনা তা পরীক্ষা করে

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

5
আপনি ধরে নিচ্ছেন যে সমাবেশটি মূল সম্পাদনযোগ্য। কোনও অতিরিক্ত প্রকল্প নয়। আপনি অযথা পুনরুক্তি করছেন যদিও একগুচ্ছ পুনরাবৃত্তি। ফ্রেমওয়ার্কটি ভারী উত্তোলন করা ভাল। তারপরে পাওয়া গেলে আরও ফিল্টার করুন। প্রাসঙ্গিক হলে, আপনার উত্তর আপডেট করুন। তালিকা অন্তর্ভুক্ত করুন <T> যুক্তি। var ClassTypesImplementingInterface = AppDomain.CurrentDomain.GetAs সমাবেশসমূহ ()। নির্বাচন করুন বহু (x => x.GetTypes ()) যেখানে (mytype => typof (myInterface) .IsAssignableFrom (mytype) & & mytype.GetInterness (Type) ইন্টারফেস টাইপ)। )); foreach (আইটেমগুলিতে var আইটেম) কনসোল.লগ (আইটেম.নাম);
তমুসজেয়ার্স

58

IFoo ইন্টারফেস প্রয়োগ করে এমন কোনও সমাবেশে সমস্ত ধরণের সন্ধান করতে:

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

দ্রষ্টব্য যে রায়ান রিনালদীর পরামর্শটি ভুল ছিল। এটি 0 প্রকার ফিরে আসবে। আপনি লিখতে পারবেন না

where type is IFoo

কারণ টাইপটি একটি সিস্টেম T টাইপ উদাহরণ, এবং কখনও কখনও আইফু টাইপ হবে না। পরিবর্তে, আপনি যদি পরীক্ষা থেকে IFoo নির্ধারিত হয় কিনা তা পরীক্ষা করে দেখুন। এটি আপনার প্রত্যাশিত ফলাফল পাবে।

এছাড়াও, অ্যাডাম রাইটের পরামর্শ, যা বর্তমানে উত্তর হিসাবে চিহ্নিত হয়েছে, এছাড়াও ভুল এবং একই কারণে। রানটাইমের সময়, আপনি 0 টি প্রকার ফিরে আসতে দেখবেন, কারণ সমস্ত System.Type উদাহরণগুলি IFoo বাস্তবায়নকারী ছিল না।


58

আমি কৃতজ্ঞ এই একটি খুব পুরানো প্রশ্ন হল কিন্তু আমি আমি তারিখ ব্যবহারের কিছু ফর্ম থেকে সব উত্তর ভবিষ্যতে ব্যবহারকারীদের জন্য অন্য উত্তর যোগ হবে চিন্তা Assembly.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

এর কারণ হল একটি রেফারেন্স ছাড়া হয় AssemblyAAssemblyCআপনাকে পারব না:

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
এটি আমাকে একটি দুর্দান্ত উদ্ভট সমস্যার সাথে মোকাবিলা করতে সহায়তা করেছিল, যেখানে আমার পরীক্ষার প্রকল্পে গেটটাইপস ব্যর্থ হবে এবং কেবল আমাদের সিআই-পরিবেশে। এই সমাধানের জন্য গেটলোয়াডেবলটাইপস একটি স্থির ছিল। স্থানীয় পরিবেশে ত্রুটিটি পুনরায় প্রজননযোগ্য হবে না এবং এটি হ'ল: সিস্টেম.প্রকাশন efপরিচয়নটি টাইপ লোড এক্সসেপশন: অনুরোধ করা ধরণের এক বা একাধিক লোড করতে অক্ষম। আরও তথ্যের জন্য লোডারএক্সেপশন সম্পত্তি পুনরুদ্ধার করুন। আরও সুনির্দিষ্টভাবে এটি অভিযোগ করছিল যে এমন একটি ধরণের ছিল যার একটি কংক্রিট বাস্তবায়ন হয়নি এবং ইউনিট পরীক্ষা প্রকল্পে এটি ঘটেছিল। এর জন্য ধন্যবাদ!
লারি তুওমিস্তো

2
এই উত্তরটি সমাধান হিসাবে চিহ্নিত করা উচিত, এটি আমার পাছাটিকে আজ রক্ষা করেছে, কারণ @ লারি তুওমিস্তো বলেছিলেন, স্থানীয় এনভির মত আমরা একই ধরণের ত্রুটি পুনরায় উত্পাদন করতে পারিনি
লাইটনিং 3

3
যদি এটি অন্য কাউকে সহায়তা করে: এই সমাধানটি আমার পক্ষে কাজ করেছে, তবে তালিকা থেকে ইন্টারফেসের ধরণটি সরাতে আমাকে এটি পরিবর্তন করতে হয়েছিল। আমি CreateInstanceতাদের সবার জন্য সক্রিয় করতে চেয়েছিলাম , এবং যখন এটি আসল ইন্টারফেস তৈরি করার চেষ্টা করছিল তখন একটি ব্যতিক্রম ছুঁড়ে ফেলা হয়েছিল (যা আমি যখন সমাধানের প্রকৃত ইন্টারফেসের বাইরে চলে আসি তখন কিছুক্ষণ আমাকে বিভ্রান্ত করে তোলে)। সুতরাং আমি কোড পরিবর্তন করে GetLoadableTypes(assembly).Where(interfaceType.IsAssignableFrom).Where(t => !(t.Equals(interfaceType))).ToList();
জাভিয়ের পেঁয়া

21

অন্যান্য উত্তর এখানে ব্যবহার করুন IsAssignableFrom। এছাড়াও আপনি ব্যবহার করতে পারেন FindInterfacesথেকে System, হিসাবে বর্ণনা নামস্থান এখানে

এখানে একটি উদাহরণ রয়েছে যা বর্তমানে কার্যনির্বাহক অ্যাসেমব্লির ফোল্ডারে সমস্ত অ্যাসেমবিলি পরীক্ষা করে, নির্দিষ্ট ইন্টারফেস প্রয়োগকারী ক্লাসগুলি সন্ধান করে (স্পষ্টতার জন্য লিনকিউ এড়ানো)।

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

আমি পেয়েছি: এসেম্বলির 'সিস্টেমের উপর নির্ভরতা সমাধান করতে পারি না ore কোর, সংস্করণ = 4.0.0.0, সংস্কৃতি = নিরপেক্ষ, পাবলিক্যকিটোকেন = b77a5c561934e089' কারণ এটি প্রিললোড হয়নি। রিফ্লেকশনঅনলি এপিআই ব্যবহার করার সময়, নির্ভরশীল অ্যাসেমব্লিশগুলি অবশ্যই রিফ্লেকশনঅনলঅ্যাসবেলস রেজোলিউশন ইভেন্টের মাধ্যমে চাহিদার উপর প্রাক লোড বা লোড হওয়া আবশ্যক।
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

সম্পাদনা: আমি এডিটটি কেবল স্পষ্ট করে দেখতে পেয়েছি যে আসল প্রশ্নটি পুনরাবৃত্তি / কোড হ্রাসের জন্য ছিল এবং এটি একটি অনুশীলন হিসাবে ভাল এবং ভাল, তবে বাস্তব-বিশ্বের পরিস্থিতিতে আপনি দ্রুততম বাস্তবায়ন চান, নির্বিশেষে অন্তর্নিহিত লিনকিউ দেখতে কত শীতল।

লোডযুক্ত ধরণের মাধ্যমে পুনরাবৃত্তি করার জন্য এখানে আমার ইউটিস পদ্ধতি। এটি আপনার নিয়মিত ক্লাসের পাশাপাশি ইন্টারফেসগুলি পরিচালনা করে এবং যদি আপনি নিজের / তৃতীয় পক্ষের কোডবেজে বাস্তবায়নগুলি সন্ধান করেন তবে ব্যতিক্রমী সিস্টেম টাইপ বিকল্পগুলি জিনিসগুলিকে প্রচুর পরিমাণে গতি দেয়।

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
গণনাকারীরা আইডিস্পোজেবল বাস্তবায়ন করেন যা চেষ্টা / অবশেষে নিষ্পত্তি হয় না। ফোরচ বা লিনক ব্যবহার করা ভাল।
TamusJRoyce 20'15

কেন excludeSystemTypesআপনি একটিতে দু'বার পরীক্ষা দিচ্ছেন if?
নেটমেজ

4

অন্যান্য উত্তর জেনেরিক ইন্টারফেসের সাথে কাজ করছে না ।

এইটি করে, কেবল টাইফফ (টি) দ্বারা টাইপফ (আইসোমিটারফেস) প্রতিস্থাপন করুন।

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

তাদের একটি তালিকায় আছে।


আপনার সমাধান কীভাবে কাজ করে এবং অন্য সমস্ত উত্তরের চেয়ে কেন এটি সর্বোত্তম is
লুকাশ কুরফার

এটি উচ্চতর বা নিম্ন নয়, অন্যান্য উত্তরগুলি আমার পক্ষে কার্যকর হয়নি এবং আমি এটি ভাগ করে নেওয়ার জন্য উদ্বিগ্ন।
আন্তোনিন গ্যাভারিল

আমার মন্তব্যটি ছিল আপনার উত্তরটি কেবল কোড-হওয়া সম্পর্কে, তাই আমি আপনাকে কিছু ব্যাখ্যা যুক্ত করতে বললাম।
Lukas Kferrfer

2

আপনি যা করতে চান তা করার কোনও সহজ উপায় (পারফরম্যান্সের দিক দিয়ে) নেই।

প্রতিচ্ছবি মূলত সমাবেশ এবং প্রকারের সাথে কাজ করে তাই আপনাকে সমস্ত ধরণের সমাবেশ পেতে এবং সঠিক ইন্টারফেসের জন্য এগুলি জিজ্ঞাসা করতে হবে। এখানে একটি উদাহরণ:

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

এটি আপনাকে সমস্ত প্রকারের সাথে পাওয়া যাবে যেগুলি আইএমআইআইন্টারফেসটি বিধানসভা মাইঅ্যাস্প্যাসেলেশনে প্রয়োগ করে


2

এমনকি সমাবেশের অবস্থান চয়ন করার সময় আরও ভাল better আপনি যদি জানেন যে আপনার প্রয়োগকৃত সমস্ত ইন্টারফেস একই অ্যাসেমব্লির মধ্যে রয়েছে তবে বেশিরভাগ অ্যাসেমব্লিকে ফিল্টার করুন efনির্ধারিত টাইপস।

// 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

আমি লিনক-কোডে ব্যতিক্রম পেয়েছি তাই আমি এটি এইভাবে করি (জটিল এক্সটেনশন ছাড়াই):

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

তালিকা পেতে আপনি কিছু লিনকিউ ব্যবহার করতে পারেন:

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

তবে সত্যিই কি আরও বেশি পঠনযোগ্য?


6
এটি আরও পাঠযোগ্য, যদি এটি কাজ করে। দুর্ভাগ্যক্রমে, যেখানে আপনার ক্লজটি সিস্টেমটি পরীক্ষা করছে কিনা তা পরীক্ষা করে দেখছে ype টাইপ শ্রেণীর কোনও আইসোমইনটারফেস প্রয়োগ করে, যা কখনই সত্য হবে না, যদি না ইসোমিইন্টারফেসটি সত্যই আইআরফলেক্ট বা আইসিস্টমঅ্যাট্রিবিউটপ্রাইডার হয়, তবে এটি সর্বদা সত্য হবে।
জোয়েল মুলার

উপরের কার্ল নায়ক উত্তরটির যেখানে ক্লজটি সংশোধন করার উত্তর রয়েছে: ইসএইসনেবলফ্রম। উত্তরের জন্য সহজ ভুল।
TamusJRoyce 20'15
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.