代码之家  ›  专栏  ›  技术社区  ›  Tomtom

比较泛型接口类型与给定类型

  •  1
  • Tomtom  · 技术社区  · 8 年前

    我试图动态地创建一个从泛型继承的类型的实例 interface

    例如,我有以下基本接口,其中派生了几个其他接口:

    public interface IDummy { }
    

    我有两个派生接口:

    public interface IDummyDerived<T> : IDummy
    {
      void Foo(T value);
    }
    
    public interface ITempDerived<T> : IDummy
    {
      void HelloWorld(T value);
    }
    

    现在我需要一个ServiceProvider类,在这里我可以创建并找到实现给定接口的类。每个接口(idummydrived和ITempDerived)只实现一次。

    internal class DummyServiceProvider
    {
      public T GetDummy<T>() where T : IDummy
      {
        Type baseType = typeof(IDummy);
        Type[] types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(p => baseType.IsAssignableFrom(p) && p.IsClass).ToArray();
        //now I have all classes which implements one of my interfaces
        foreach(Type type in types)
        {
          // here I want to check if the current type is typeof(T)
          // (typeof(T) == type) ->  doesn't work
          // (type.GetGenericTypeDefinition() == type) doesnt work
    
        }
      }
      return default(T);
    }
    

    如何正确比较给定的 typeof(T) 到类型数组中的类型?

    --更新:

    DummyServiceProvider的用法如下所示:

    IDummyDerived<string> dummyDerived = myDummyServiceProvider.GetDummy<IDummyDerived<string>>()

    3 回复  |  直到 8 年前
        1
  •  0
  •   Andre    8 年前

    一个更简单的解决方案是重写你的where,如下所示

    string nameOfIDummy = typeof(IDummy).Name;
    string nameOfT = typeof(T).Name;
    IEnumerable<Type> classTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(p => p.IsClass && p.GetInterface(nameOfIDummy) != null && p.GetInterface(nameOfT ) != null);
    

        2
  •  0
  •   Community Mohan Dere    6 年前

    你在检查 base generic interface type 具有 derived type

    参见下面的代码

    using System;
    using System.Reflection;
    using System.Linq;
    
    namespace AssemblyLoadRefelectionExp
    {
        public class MyClass
        {
            public string Key { get; set; }
        }
    
        public interface IDummy { }
    
        public interface IDummyDerived<T> : IDummy
        {
            void Foo(T value);
        }
    
        public interface ITempDerived<T> : IDummy
        {
            void HelloWorld(T value);
        }
    
        public class DummyDerived<T> : IDummyDerived<T>
        {
            public void Foo(T value)
            {
                Console.WriteLine("DummyDerived`1 ->Foo");
            }
        }
    
        public class AnotherDummy : IDummyDerived<string>
        {
            public void Foo(string value)
            {
                Console.WriteLine("AnotherDummy -> Foo");
            }
        }
    
        public class Program
        {
            public static void Main()
            {
                Console.WriteLine($"Is {typeof(DummyDerived<MyClass>)} equal to {typeof(IDummyDerived<MyClass>)} : {CheckType<DummyDerived<MyClass>>(typeof(IDummyDerived<MyClass>))}");
                Console.WriteLine("---------------------------------");
                GetDummy<IDummyDerived<string>>();
    
                Console.ReadLine();
            }
    
            public static bool CheckType<T>(Type type)
            {
                return typeof(T) == type ? true : false;
            }
    
            public static T GetDummy<T>() where T : IDummy
            {
                Type baseType = typeof(IDummy);
                Type[] types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(p => baseType.IsAssignableFrom(p) && p.IsClass).ToArray();
                //now I have all classes which implements one of my interfaces
                foreach (Type type in types)
                {
                    Console.WriteLine($"Is {type.Name} assignable from {typeof(T)} : {typeof(T).IsAssignableFrom(type)}");
                }
    
                return default(T);
            }
        }
    }
    

    输出为

    正在组装lyLoadRefelectionExp.dummy导出 1[AssemblyLoadRefelectionExp.MyClass] equal to AssemblyLoadRefelectionExp.IDummyDerived 1[装配lyLoadRefelectionExp.MyClass类]:错误`


    Dummy是派生的吗 1 assignable from AssemblyLoadRefelectionExp.IDummyDerived 1[系统字符串]:错误

    是否可以从Assemb分配另一个虚拟对象lyLoadRefelectionExp.idummydrived文件`1[系统字符串]:正确

    IsAssignableFrom 方法自 GetDummy 方法正在用调用 IsAssignableFrom公司