Сравните тип универсального интерфейса с данным типом - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь динамически создать экземпляр типа, который наследуется от общего interface.

Например, у меня есть следующий базовый интерфейс, из которого получены несколько других интерфейсов:

public interface IDummy { }

И у меня есть два производных интерфейса:

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

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

Теперь мне нужен ServiceProvider-Class, где я могу создать классы, которые реализуют данный интерфейс.Каждый интерфейс (IDummyDerived и 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 ]

0 голосов
/ 29 мая 2018

Более простым решением было бы переписать ваше где следующим образом

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

Может быть, вы могли бы написать, для чего вам это нужно, я не понимаю вариант использования, и для меня это кажется странной вещью.

0 голосов
/ 30 мая 2018

Вы проверяете равенство между 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);
        }
    }
}

, который выдает результат как

Is AssemblyLoadRefelectionExp.DummyDerived 1[AssemblyLoadRefelectionExp.MyClass] equal to AssemblyLoadRefelectionExp.IDummyDerived 1 [AssemblyLoadRefelectionExp.MyClass]: False`


Is DummyDerived 1 assignable from AssemblyLoadRefelectionExp.IDummyDerived 1 [System.String]: False

IsAnotherDummy, присваиваемый из AssemblyLoadRefelectionExp.IDummyDerived`1 [System.String]: True

Если вы включите приведенный выше код, чтобы проверить базовый тип с производным типом, я использовал здесь IsAssignableFrom методтак как метод GetDummy вызывается с base generic interface type.IsAssignableFrom подтверждает, что экземпляр указанного типа может быть назначен экземпляру текущего типа.

0 голосов
/ 29 мая 2018

Взгляните на этот пост:

C # Сравнение типов: Type.Equals vs operator ==

Принятый ответ здесь гласит:

Console.WriteLine(type.Equals(typeof(int))); // Prints True
Console.WriteLine(type == typeof(int));      // Prints False

Ваш пост не является дубликатом, но принятый ответ может помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...