2

私が作成している小さなプロジェクトがあり、特定のインターフェイスから継承するすべてのクラスのインスタンスを取得できるかどうかを調べようとしています。

私が達成しようとしていることの簡単な例を次に示します。

public interface IExample
{
    string Foo();
}

public class Example1 : IExample
{
    public string Foo()
    {
        return "I came from Example1 !";
    }
}

public class Example2 : IExample
{
    public string Foo()
    {
        return "I came from Example2 !";
    }
}

//Many more ExampleN's go here

public class ExampleProgram
{

    public static void Main(string[] args)
    {
        var examples = GetExamples();

        foreach (var example in examples)
        {
            Console.WriteLine(example.Foo());
        }
    }

    public static List<IExample> GetExamples()
    {
        //What goes here?
    }
}

GetExamples メソッドがインターフェイス IExample から継承する各クラスのインスタンスを含むリストを返す方法はありますか (ハードコーディングする以外に) ありますか? あなたが与えることができる洞察は大歓迎です。

4

4 に答える 4

2

参照:クラスがジェネリック クラスから派生しているかどうかを確認する

また:リフレクションを介したインターフェースの実装(これはまさにあなたが望むものかもしれません)

基本的には、ターゲット アセンブリ内のすべての型を列挙し、インターフェイスが実装されているかどうかをテストするだけで済みます。

于 2009-07-30T03:38:13.573 に答える
1

マットのソリューションに基づいて、次のように実装します。

public static List<IExample> GetExamples()
{
    return GetInstances<IExample>().ToList();
}

private static IEnumerable<T> GetInstances<T>()
{
    return Assembly.GetExecutingAssembly().GetTypes()
        .Where(type => type.IsClass &&
                       !type.IsAbstract &&
                       type.GetConstructor(Type.EmptyTypes) != null &&
                       typeof (T).IsAssignableFrom(type))
        .Select(type => (T) Activator.CreateInstance(type));
}

このソリューションは、抽象クラス、派生インターフェイス、デフォルト (パラメーターなし) のパブリック コンストラクターを持たないクラスなど、インスタンス化できない型をスキップします。

于 2009-07-30T04:12:26.853 に答える
0

これが私がそのようなことをする方法です:

    public static List<IExample> GetExamples()
    {
        var assembly = Assembly.GetExecutingAssembly();
        var types = assembly.GetTypes().Where(t => t.GetInterfaces().Any(i => i == typeof(IExample))).ToList();

        List<IExample> returnMe = new List<IExample>();
        foreach (var type in types)
            returnMe.Add((IExample) Activator.CreateInstance(type));

        return returnMe;
    }
于 2009-07-30T03:45:34.777 に答える
0

リフレクションを使用する必要があります。

Assembly.GetExecutingAssemblyあなたの出発点になるはずです。

編集:役立つコード

Type[] types = Assembly.GetExecutingAssembly().GetTypes();
foreach(Type tp in types)
{
    if (typeof(IExample).IsAssignableFrom(tp))
    {
        if (tp.IsInterface == false)
        {
            IExample t = Activator.CreateInstance(tp) as IExample;
            Console.WriteLine(t.Foo());
        }
    }
}
于 2009-07-30T03:39:13.710 に答える