Список, который принимает только несколько типов - PullRequest
3 голосов
/ 29 марта 2012

Существует ли в каком-либо пространстве имен System в C # контейнер, который может принимать только некоторые типы? Например, я хочу создать свой список, в котором у меня будут только объекты типа Class1 и int:

//accept only type Class1 and int;
MYLIST lst = new MYLIST(typeof(Class1), typeof(int));
lst.Add( 23 ); // OK
lst.Add( new Class1() ); // OK
lst.Add( "text" ); // wrong, not accepted type

Что-то подобное в .NET или я должен написать это самостоятельно? Спасибо.

Ответы [ 5 ]

3 голосов
/ 29 марта 2012

Система типов C # не позволяет вам выражать что-то вроде "либо Class1, либо int".Сказав это, вы можете использовать перегрузки, чтобы получить половину пути:

class MyClass
{
    private List<object> _items = new List<object>();
    public void Add(int value) { _items.Add(value); }
    public void Add(Class1 value) { _items.Add(value); }
    ...
}

Реальный сложный вопрос заключается в том, как вы получаете вещи из , а не как вы помещаете вещи в .Есть несколько возможностей: вывести все как object (путем реализации IEnumerable<object>) и, возможно, специальные методы, такие как GetInt(int index) и GetClass1(int index).

1 голос
/ 29 марта 2012

Ответ НЕТ, такого списка нет в C # и по ОЧЕНЬ ХОРОШЕЙ причине.

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

 public class CustomListWrapper< T, F>
    {
        private readonly List<object> internalList;
        public CustomListWrapper()
        {
            this.internalList = new List<object>();
        }

        public void Add(object item)
        {
            if(!(item is T || item is F))
                throw new Exception();

            this.Add(item);
        }

    }

PS: до понижения, о том, как вывести объект ... ну, вот почему это довольно плохая идея, но вам нужно будет сделать "is" на типе, который вы получаете, чтобы иметь возможность его разыграть.к правильному типу.

Опять же, не совсем уверен, зачем вам это когда-либо понадобилось.

1 голос
/ 29 марта 2012

Нет. Вам придется создать свой собственный. Вы можете реализовать ICollection или IEnumerable или IList или что-то еще. У вас есть много гибкости здесь. Но суть в том, что ответ - нет, такой коллекции не существует, которая позволяет автоматически ограничивать типы в коллекции определенными типами.

1 голос
/ 29 марта 2012

Вы не можете достичь этого прямым способом. Тип элемента List<T> должен быть базовым типом, общим для всех типов, которые вы хотите добавить в список.

Вы можете иметь List<object> или обертку вокруг List<object> причины. Однако во время выполнения вам нужно будет проверить, имеют ли добавленные к нему элементы правильные типы, и вам придется преобразовать элементы, полученные из списка, в правильный тип.

Если вы хотите хранить разные типы в одном и том же списке, хорошим вариантом будет создание интерфейса, который должны реализовывать все эти типы

public interface ICommonInterface
{
    int Number { get; }
    string Text { get; }
}

public Class1 : ICommonInterface
{
    public int Number { get; set; }
    public string Text { get; set; }

    public string AnAdditionalProperty { get; set; }
}

public NumberWrapper : ICommonInterface
{
    public NumberWrapper (int number)
    {
        this.Number = number;
        this.Text = number.ToString();
    }

    public int Number { get; private set; }
    public string Text { get; private set; }
}

public TextWrapper : ICommonInterface
{
    public TextWrapper (string text)
    {
        this.Text = text;
        int i;
        Int32.TryParse(text, out i);
        this.Number = i;
    }

    public int Number { get; private set; }
    public string Text { get; private set; }
}

Тогда вы можете объявить свой список как

List<ICommonInterface> lst = new List<ICommonInterface>();
lst.Add(new Class1());
lst.Add(new NumberWrapper(77));
lst.Add(new TextWrapper("hello"));

Console.WriteLine(lst[0].Text);
0 голосов
/ 29 марта 2012

почему бы просто не обернуть List <> и создать два метода add, один из которых принимает int, а другой принимает Class1

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