Объявить список ссылок на классы - PullRequest
0 голосов
/ 28 мая 2018

Мне нужно объявить список ссылок на классы.В частности, список классов, которые реализуют интерфейс, который здесь я назову IInterface.

Подобно тому, как List может быть списком типов и выглядеть следующим образом:

List<Type> types = new List<Type> {string, bool, int, float};

Мне нужно выполнить то же самое, где каждый из них является моим собственным классом, и реализовать интерфейс IInterface так:

List<(idk)> references = new List<(idk)> {myClass, myClass2, myClass3};

и все они MyClass : IInterface, MyClass2 : IInterface и MyClass3 : IInterface.

Мне это нужно, чтобы при создании экземпляра типа компилятор знал, что тип реализует IInterface.

Ответы [ 3 ]

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

Мне нужно это, чтобы при создании экземпляра типа компилятор узнал, что тип реализует IInterface.

Ниже я покажу вам два возможных способа полученияСписок type тех классов, которые реализуют IInterface.Поэтому при создании нового объекта вы можете использовать этот список, чтобы решить, реализует ли этот класс IInterfce или нет.

  • Решение времени компиляции

Если вы хотите решение во время компиляции, вы должны иметь List<IInterface>, тогда в этот список будут включены только те объекты классов, которые реализуют IInterface.Имея этот список (в котором есть только те объекты классов, которые реализуют IInterface, используйте этот список для подготовки списка типов.

Например:

class Demo реализует IInterfaceи Demo2 нет.

    List<IInterface> listOfIInterface = new List<IInterface>();
    listOfIInterface.Add(new Demo());
    listOfIInterface.Add(new Demo2()); //this line will have compile time error

теперь используйте этот список для подготовки списка типов

    List<Type> listOfIInterfaceType = new List<Type>();
    foreach(object obj in listOfIInterface)
    {
        listOfIInterfaceType.Add(obj.GetType());
    }
  • Время выполнения Решение

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

Если существует несколько классов, и вы хотите знать, какой класс реализует IInterface, и выбрать тип этого класса всписок. Вы можете попробовать следующий код.

Предположим, есть два класса Demo и Demo2. Demo реализует IInterface, в то время как Demo2 нет.

если у вас есть объект обоих классов, вы помещаете их в список Object и зацикливаете этот список и выполняете следующую логику.

    List<object> listOfObject = new List<object>();
    listOfObject.Add(new Demo()); //Demo Implements IInterface
    listOfObject.Add(new Demo2());//Demo2 doesn't Implement IInterface

    //this will have all possible types
    List<Type> listOfAllType = new List<Type>();
    //this will have type of those class, which implement interface
    List<Type> listOfInterfaceType = new List<Type>();
    //this will have objet of those class, which implement interface.
    List<object> listOfInterfaceObject = new List<object>();

    foreach (object obj in listOfObject)
    {
        Type type = obj.GetType();
        if (!listOfAllType.Contains(type))
            listOfAllType.Add(obj.GetType());

        IInterface testInstance = obj as IInterface;
        if (testInstance != null)
        {
            if (!listOfInterfaceType.Contains(type))
                listOfInterfaceType.Add(type);
            if (!listOfInterfaceObject.Contains(obj))
                listOfInterfaceObject.Add(obj);
        }
    }

Обратите внимание, что если какой-либо класс не реализует интерфейс, это объектне может быть приведен к ИнтерфейсуКласс не реализует интерфейс.

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

Если вы хотите в основном List<Type>, где Type требуется для реализации интерфейса, и вы хотите, чтобы это было принудительно применено во время компиляции, это на самом деле возможно, если обернуть List<Type> и заставить метод add иметьпараметр ограниченного универсального типа и использование его для добавления в список, но его использование может быть немного неуклюжим (вы не сможете использовать синтаксис инициализатора коллекции, на который вы ссылаетесь в своем вопросе):

public class TypeList<T> : IEnumerable<Type>
{
    private List<Type> _list = new List<Type>();

    public void Add<TAdd>() where TAdd : T
    {
        _list.Add(typeof(TAdd));
    }

    public IEnumerator<Type> GetEnumerator() => _list.GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
}

Параметр универсального типа для этого класса - это тип, к которому вы хотите привязать список, поэтому в вашем примере использование списка будет выглядеть так:

var list = new TypeList<IInterface>();
list.Add<MyClass>();
list.Add<MyClass2>();
list.Add<MyClass3>();

И эти компиляции не удастся:

list.Add<string>();
list.Add<bool>();
list.Add<int>();
list.Add<float>();
0 голосов
/ 28 мая 2018

Вы просто после List<Type> здесь с TypeOf(myClass), TypeOf(myClass2)... в качестве значений.Вам нужно будет сделать дополнительную проверку, если вы действительно хотите убедиться, что эти типы реализуют IInterface.Вы не можете указать во время компиляции, что типы должны быть только теми, которые реализуют ваш интерфейс.

Помимо этого, это звучит как предварительное условие для внедрения зависимостей, вы можете захотеть использовать среду внедрения зависимостей Microsofts Unity, если этодело.

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