C #: Реализация двух абстрактных списков в неуниверсальном классе? - PullRequest
6 голосов
/ 02 февраля 2011

Извините за глупый заголовок, понятия не имел, как произнести это

Я создаю класс, который имеет два списка одного типа.Он используется для копирования ссылки на объект в первом списке во второй список.

Хотя оба списка будут одного и того же типа (содержат один и тот же тип объекта), он может отличаться каждый раз, когда этот классinitialized.

Так что я предполагаю, что должен сделать типы List как своего рода абстрактный список.Я хотел бы убедиться, что они будут строго типизированы при создании экземпляра (но не обязательно, если возникнут проблемы).Проблема заключается в методе, который перемещает выбранные элементы из списка1 в список абстрактных типов списка 2. Обычно для этого нет методов.

Я думаю, что нормальным решением было бы сделать класс универсальным (className <T> thingy) но я не уверен, что смогу сделать это (по крайней мере, я не знаю как), потому что этот класс наследует пользовательский контроль WPF.

Вот код:

public partial class SubsetSelectionLists : UserControl
{
    public static DependencyProperty SetCollectionProperty = DependencyProperty.Register("SetCollection", typeof("Need a abstract list type here"), typeof(SubsetSelectionLists));
    public static DependencyProperty SubsetCollectionProperty = DependencyProperty.Register("SubsetCollection", typeof("Need a abstract list type here"), typeof(SubsetSelectionLists));

    public "Need a abstract list type here" SetCollection
    {
        get
        {
            return ("Need a abstract list type here") GetValue(SetCollectionProperty);
        }
        set
        {
            SetValue(SetCollectionProperty, value);
        }
    }

    public "Need a abstract list type here" SubsetCollection
    {
        get
        {
            return ("Need a abstract list type here")GetValue(SubsetCollectionProperty);
        }
        set
        {
            SetValue(SubsetCollectionProperty, value);
        }
    }

    public SubsetSelectionLists()
    {
        InitializeComponent();
        SubsetSelectiongrid.DataContext = this;
    }

    private void selectionBtnClick(object sender, RoutedEventArgs e)
    {
        SubsetCollection.AddTheseItems(SET.SelecctedItems)
    }

    private void removeBtnClick(object sender, RoutedEventArgs e)
    {
        SUBSET.RemoveTheseItems(SUBSET.SelectedItem);
    }
}

РЕДАКТИРОВАТЬ: Решение

Некоторые ответы указали мне на оптимальное решение создания Общего Класса.Однако это может быть проблематично в WPF.Вам придется пропустить XAML в универсальном классе верхнего уровня.

Это будет означать, что вы можете выполнять XAML в дочерних классах, зависящих от типа, а это не то, что вы хотели бы делать (если только не кодэто то, что вы бы использовать повторно, но внешний вид является переменной).Вы могли бы также спроектировать элемент управления, используя код, я думаю, но я не уверен, насколько это будет эффективно.

Меня указали на объект IList, который является абстрактным списком, от которого наследуются многие другие, и ясобираюсь использовать.Это что-то вроде хака, но так как он не будет использоваться в открытой библиотеке, я согласен с этим.В противном случае я бы использовал общий маршрут.

Ответы [ 3 ]

3 голосов
/ 02 февраля 2011

Как-то так, или я стреляю далеко от цели?

3 голосов
/ 02 февраля 2011

Я не знаю, насколько хорошо дизайнеры играют с пользовательскими элементами управления, которые являются общими классами.Если это проблема (о которой я бы догадался), то одним из способов избежать этого является раскрытие коллекций IList, но при этом использование List<T>, созданных во время выполнения для обеспечения безопасности типов в хранилище (пример кода сокращен довключать только создание объектов списка и свойства для их предоставления; при необходимости добавьте код для DependencyProperty и т. д.):

public class YourControl : UserControl
{

    // this method will set up the internal lists for accepting
    // objects of the specified type only
    public void SetListType(Type containedType)
    {
        var listType = typeof(List<>).MakeGenericType(new[] { containedType });
        SetCollection = (IList)Activator.CreateInstance(listType);
        SubsetCollection = (IList)Activator.CreateInstance(listType);
    }
    public IList SetCollection { get; private set; }
    public IList SubsetCollection { get; private set; }
}

// usage example:
theControl.SetListType(typeof(string));
theControl.SetCollection.Add("some string"); // works ok
theControl.SetCollection.Add(42); // fails, 42 is not a string

Очевидным недостатком является то, что SetCollection и SubsetCollection предоставляют "нетипизированный" object списков.

2 голосов
/ 02 февраля 2011

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

  partial class GenericClass1<T> : UserControl
  {
    private List<T> _list;
  }

РЕДАКТИРОВАТЬ накомментарии ниже

Определите типизированные классы, которые фиксируют универсальный тип в вышеприведенном классе (и может использоваться дизайнером), т.е.

partial class IntClass1 : GenericClass1<int> {}

partial class StringClass1 : GenericClass1<string> {}

....

Конечно, это действительно работает только если у васограниченный / статический набор типов, которые вы хотите сохранить в своих списках

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