泛型类型'导致问题c#.net

本文关键字:问题 net 泛型类型 | 更新日期: 2023-09-27 18:16:28

我有一个名为GroupItem的类,我可以在这里存储任何类型,例如int, string, decimal, datetime等。然后,我有GroupItems,它将存储任何groupItem。我使用数组列表来存储所有的groupItem。

public class GroupItem<T>
{
    private string heading;
    private List<T> items = new List<T>();
    public GroupItem() { }
    public string Heading
    {
        get { return heading; }
        set { heading = value; }
    }
    public List<T> Items
    {
        get { return items; }
        set { items = value; }
    }
    public void Add(T value)
    {
        this.items.Add(value);
    }
    public T this[int index]
    {
        get
        {
            return this.items[index];
        }
    }
}
public class GroupItems
{
    private string groupName;
    private List<object> items = new List<object>();
    public string GroupName
    {
        get { return groupName; }
        set { groupName = value; }
    }
    public GroupItems() { }
    public void Add(object value)
    {
        this.items.Add(value);
    }
    public object this[int index]
    {
        get
        {
            return this.items[index];
        }
    }
}

我想从GroupItems中检索。我怎么能得到通用项目的值在groupItems?

我现在插入两个项目,datetime和int组项目。现在我想检索groupitems[2]值,但我如何将其转换为groupItem而不知道它是什么。甚至我们可以通过getType(). getgenericarguments()[0]获得它的泛型参数。但是如何创建一个实例呢?

泛型类型'导致问题c#.net

如果列表存储异构项,那么我建议您需要一个通用的非泛型接口或基类。比如我们输入

interface IGroupItem {
// the non-generic members, and maybe
// "object Value {get;}" etc, and maybe
// "Type ItemTypr {get;}"
}

你会得到:

class GroupItem<T> : IGroupItem {...}

,然后使用

List<IGroupItem> ...

代替ArrayList,或者,坦率地说,代替GroupItems{…}

我要做的是创建一个通用集合,如:

public class GroupItems<T> : List<GroupItem<T>>
{
}

如果您需要扩展列表的基本功能,您还可以扩展Collection<T>并覆盖您需要的方法:

public class GroupItems<T> : Collection<GroupItem<T>>
{
    protected override void InsertItem(int index, T item)
    {
         // your custom code here
         // ...
         // and the actual insertion
         base.InsertItem(index, item);
    }
}

将您的GroupItems类替换为List<GroupItem<T>>如何?

根据您对GroupItem所做的操作,您应该继承由其他提供的List/Collection或在您的类中使用泛型集合例如

    class GroupItem<T> 
{
    private List<T> items = new List<T>();
    public void Add(T value)
    {
        items.Add(value);

    }
    public T Get()
    {
       //replace with some logic to detemine what to get
       return items.First();
    }
}

你的问题可以涵盖两种情况:

  1. 您想简单地将T类型的GroupItem的集合存储在GroupItems类中。
  2. 你想在类GroupItems中存储任何类型的通用GroupItem的集合。为了更好地澄清,我的意思是您可以将GroupItem<DateTime>GroupItem<int>存储在同一个GroupItems类中。

下面是针对这两种场景进行存储和检索的一些方法:

相同类型

public class GroupItem<T>
{
    // ... Code for GroupItem<T>
}
public class GroupItems<T>
{
    private List<GroupItem<T>> mItems = new List<GroupItem<T>>();
    public void Add(T item)
    {
        mItems.Add(item);
    }
    public T GetItem(int index)
    {
        return mItems[index];
    }
}

在这里,您将构建一个同时包含GroupItem的集合,例如GroupItem<DateTime>的集合。所有的项目将是相同的类型。

泛型

public interface IGroupItem
{
    // ... Common GroupItem properties and methods
}
public class GroupItem<T>
{
    // ... Code for GroupItem<T>
}
public class GroupItems
{
    private List<IGroupItem> mItems = new List<IGroupItem>();
    public void Add(IGroupItem item)
    {
        mItems.Add(item);
    }
    // This is a generic method to retrieve just any group item.
    public IGroupItem GetItem(int index)
    {
        return mItems[index];
    }
    // This is a method that will get a group item at the specified index
    // and then cast it to the specific group item type container.
    public GroupItem<T> GetItem<T>(int index)
    {
        return (GroupItem<T>)mItems[index];
    }
}

在这里,您将能够构建和维护一个可以包含任何GroupItem和任何Type的单个集合。因此,您可以有一个GroupItems集合,其中包含GroupItem<DateTime>, GroupItem<int>等项目。

请注意,这些代码示例都没有考虑到任何错误的情况。

考虑:你有一个项目集合;这些项可以是任何运行时类型(string、int等)。因此,集合项的静态类型必须是object。

似乎您希望能够从具有强静态类型的列表中检索项。如果没有大量的条件逻辑(或反射),这是不可能的。例如:

object item = collection[0];
if (item is int)
    //do something with an int
else if (item is string)
    //do something with a string

现在假设我们不是对collection[0]的值"做点什么",而是将其赋值给一个变量。我们可以做以下两件事之一:

  • 对这两种情况使用相同的变量,在这种情况下静态类型必须是object。
  • 使用单独的变量,在这种情况下,静态类型将是string或int,但在条件逻辑之外,我们无法知道哪个变量保存collection[0]的值。

两个选项都不能真正解决问题。

通过创建GroupItem<T>,您为这个问题添加了一个间接级别,但是潜在的问题仍然存在。作为练习,试着重新设计这个例子,但从"考虑:你有一个项目的集合;这些项的类型是GroupItem<T>,其中T可以是任何运行时类型(string, int等)。"

谢谢你的建议。

我已经用多个重载方法解决了这个问题。

例如:

private void Print(GroupItem<string> items)
{
///custom coding
}
private void Print(GroupItem<int> items)
{
///custom coding
}

虽然它不够高效,但我想这样做,因为它是。net 2.0。

我现在正在。net 4.0中使用新的算法改进这个。

非常感谢你的帮助。