泛型类型'导致问题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]获得它的泛型参数。但是如何创建一个实例呢?
如果列表存储异构项,那么我建议您需要一个通用的非泛型接口或基类。比如我们输入
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();
}
}
你的问题可以涵盖两种情况:
- 您想简单地将
T
类型的GroupItem
的集合存储在GroupItems
类中。 - 你想在类
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中使用新的算法改进这个。
非常感谢你的帮助。