导致问题C#.net的泛型类型

时间:2011-12-03 09:27:40

标签: c# generics

我有一个名为GroupItem的类,我可以存储任何类型,例如int,string,decimal,datetime等。然后,我有GroupItems,它将存储任何groupItem。我正在使用arraylist来存储所有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中获得通用项的值?

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

7 个答案:

答案 0 :(得分:1)

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

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

然后你会:

class GroupItem<T> : IGroupItem {...}
然后你会使用

List<IGroupItem> ...

而不是ArrayList,或者,franky,代替GroupItems {...}

答案 1 :(得分:0)

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

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);
    }
}

答案 2 :(得分:0)

如何用List<GroupItem<T>>替换GroupItems类?

答案 3 :(得分:0)

根据你对GroupItem的处理方式,你应该像其他人一样继承List / Collection,或者在你的类中使用泛型集合 e.g。

    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();

    }

}

答案 4 :(得分:0)

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

  1. 您只想在班级GroupItem中存储TGroupItems的集合。
  2. 您希望在班级GroupItem中存储任何类型的通用GroupItems的集合。为了更好地澄清,我的意思是您可以将GroupItem<DateTime>GroupItem<int>存储在同一个GroupItems类中。
  3. 以下是两种方案的存储和检索方法:

    相同类型

    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];
        }
    }
    

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

    请注意,这些代码示例均未考虑任何错误情况。

答案 5 :(得分:0)

考虑一下:你有一系列物品;这些项可以具有任何运行时类型(字符串,整数等)。因此,集合项的静态类型必须是对象。

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

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]的值“做某事”,而是将值赋给变量。我们可以做以下两件事之一:

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

这两种选择都无法解决问题。

通过创建GroupItem<T>,您可以为此问题添加一个间接级别,但基础问题仍然存在。作为练习,尝试重新编写示例,但从“考虑:您有一组项目;项目类型为GroupItem<T>,其中T可以是任何运行时类型(字符串,整数等)。 )“。

答案 6 :(得分:0)

感谢您的投入。

我自己使用多种重载方法解决了这个问题。

例如:

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

虽然效率不高,但我想以这种方式做,因为它是.net 2.0。

我现在正在使用新算法改进.Net 4.0。

非常感谢您的所有帮助。