【问题标题】:C# : Implementation of two abstract lists within a non-generic class?C#:在非泛型类中实现两个抽象列表?
【发布时间】:2011-02-02 12:41:10
【问题描述】:

抱歉标题太笨了,不知道怎么写

我正在创建一个具有两个相同类型列表的类。它用于将第一个列表中的对象的引用复制到第二个列表中。

虽然两个列表将属于同一类型(包含相同类型的对象),但每次初始化此类时可能会有所不同。

所以我猜我应该将 List 类型作为某种抽象列表。我想确保它们在实例化时会被强类型化(但如果有问题则不是必需的)。问题在于将所选项目从 list1 移动到 list2 的方法内部,抽象列表类型通常没有相应的方法。

我想正常的解决方案是使类成为通用类(className<T>thingy),但我不确定我能做到这一点(至少我不知道如何),因为这个类继承了 WPF UserControl。

代码如下:

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 对象,它是许多其他人继承的抽象列表,我将使用它。这有点 hack,但由于它不会在开放库中使用,我可以接受。否则我会使用通用路由。

【问题讨论】:

  • 有什么理由不能在 linq 中做到这一点?你的 .net 版本有限制吗?
  • 什么 .net 版本。 Linq 和泛型应该能够做到这一点
  • 我不明白 linq 在这里如何帮助我?请回答它是如何完成的。我正在使用 .net 3.5,但可能会升级到 4.0

标签: c# generics collections user-controls abstract-class


【解决方案1】:

我不知道设计人员如何使用通用类的用户控件。如果这是一个问题(我猜想),解决这个问题的一种方法是公开集合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

明显的缺点是SetCollectionSubsetCollection 暴露了“无类型”object 列表。

【讨论】:

  • 好吧,这个很有用。我可以使用 IList,因为它实现了 Add 方法。我只是把 IList 放在它说“这里需要一个抽象列表类型”的任何地方,然后确保我绑定了一个继承 IList 的列表(在我的例子中是 ObservableCollection)。每个列表都是类型安全的,但我不确保它们具有相同的类型。
【解决方案2】:

类似这样的事情还是我偏离了目标?

public partial class SubsetSelectionLists<T> : UserControl
{
    public List<T> SetCollection { get; set; }

    public List<T> SubsetCollection { get; set; }

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

    private void selectionBtnClick(object sender, RoutedEventArgs e)
    {
        SubsetCollection.AddRange(SetCollection);
    }

    private void removeBtnClick(object sender, RoutedEventArgs e)
    {
        SubsetCollection.RemoveAll(x => SetCollection.Contains(x));
    }
}

【讨论】:

  • 好吧,正如我在问题中所说,这就是通常的做法。但是,由于它继承自 WPF userControl,因此它似乎不起作用。
  • 我会将该类标记为抽象类,然后创建从它继承的控件类,以便您可以指定类型。
  • 我仍然需要最初继承 UserControl 类,这将确保我必须跳过 XAML 代码并设计代码或每个子项的外观(这就是我想要的首先避免)。如果我跳过部分内容并忽略 XAML,我可以使用你的方式,所以我给你投票有用。
【解决方案3】:

正如您所说,泛型类是实现此目的的方法,您可以在从非泛型父类继承时做到这一点,例如

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

编辑基于下面的 cmets

在上面的类中定义固定泛型类型的类型化类(并且可以被设计者使用),即

partial class IntClass1 : GenericClass1<int> {}

partial class StringClass1 : GenericClass1<string> {}

....

当然,这只有在您想在列表中保存一组有限/静态的类型时才真正有效

【讨论】:

  • 只要非泛型父级不是 WPF UserControl 类。我尝试这样做,请注意它是一个部分类,并且该类的其余部分在 XAML 中声明。我发现帖子声称您无法制作通用用户控件。
  • 一旦你定义了你的泛型类,你就不能定义类型化的子类作为 WPF 用户控件吗?
  • 问题是我无法将部分的另一半定义为通用的,即 XAML 中的代码。该类只是无法编译。我可以在没有 XAML 部分的情况下创建类,但是我需要在代码或我不想发生的所有子类中设计外观(在所有子类中也是相同的)。我将您的帖子标记为有用。
猜你喜欢
  • 2012-10-31
  • 2020-05-14
  • 2013-03-06
  • 1970-01-01
  • 2018-10-29
  • 1970-01-01
  • 1970-01-01
  • 2012-12-10
  • 1970-01-01
相关资源
最近更新 更多