这是一个关于泛型的两 (2) 部分问题
我必须创建几个类似的类来模拟设计类似的数据库表。
所有表都包含一个 ID int
和一个 Text nvarchar(50)
字段。一两个可能包含一些其他字段。
我很少用 generics ,但我经常在这里看到它的例子。这是我最大的尝试创建一个泛型类用于另一个泛型类。
我的基本构造如下,我将通过注释指出不起作用的地方以及 Visual Studio 2010 显示的错误消息:
public class IdText {
public IdText(int id, string text) {
ID = id;
Text = text;
}
public int ID { get; private set; }
public string Text { get; private set; }
}
public class TCollection<T> : IEnumerable<T> where T : IdText {
private List<T> list;
public TCollection() {
list = new List<T>();
}
public void Add(int id, string text) {
foreach (var item in list) {
if (item.ID == id) {
return;
}
}
list.Add(new T(id, text)); // STOP HERE
// Cannot create an instance of the variable type 'T'
// because it does not have the new() constraint
}
public T this[int index] {
get {
if ((-1 < 0) && (index < list.Count)) {
return list[index];
}
return null;
}
}
public T Pull(int id) {
foreach (var item in list) {
if (item.ID == id) {
return item;
}
}
return null;
}
public T Pull(string status) {
foreach (var item in list) {
if (item.Text == status) {
return item;
}
}
return null;
}
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator() {
foreach (var item in list) yield return item;
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return list.GetEnumerator();
}
#endregion
}
Visual Studio 的 IntelliSence 要我添加 list.Add(T item)
,但我需要先创建它。
我试图将有问题的行 list.Add(new T(id, text));
重写为 list.Add(new IdText(id, text));
,但随后我收到消息 “无法从 IdText
转换为 T
”。
我该如何解决这个问题?
下一步: 当我稍后实际创建此 IdText
类的一个版本时,我不确定如何在 TCollection
我为它设计的类。
例如,给定这个派生类:
public class ManufacturedPart : IdText {
public ManufacturedPart(int id, string partNum, string description)
: base(int id, string partNum) {
Description = description;
}
public string Description { get; private set; }
}
...我是否还需要派生一个特殊版本的 TCollection
来配合它,就像这样?
public class ManufacturedParts<T> : IEnumerable<T> where T : ManufacturedPart {
// OK, now I'm lost! Surely this can't be right!
}
最佳答案
1) 您可以使用 new()
约束,公开您的属性并添加无参数构造函数:
public class IdText
{
public IdText()
{
}
public IdText(int id, string text)
{
ID = id;
Text = text;
}
public int ID { get; set; }
public string Text { get; set; }
}
public class TCollection<T> : IEnumerable<T> where T : IdText, new()
{
private List<T> list;
public TCollection()
{
list = new List<T>();
}
public void Add(int id, string text)
{
foreach (var item in list)
{
if (item.ID == id)
{
return;
}
}
list.Add(new T { ID = id, Text = text });
}
}
2) 你有多种选择:
如果您希望您的集合存储任何 IdText
(ManufacturedPart
或从 IdText
派生的任何其他内容):
TCollection<IdText> ss = new TCollection<IdText>();
目前,当您在 Add(int, string)
方法中实例化对象时,上面的代码只能存储 IdText
,但是如果您提供 Add (T object)
方法,它可以存储任何 IdText
实例。
如果您希望您的集合仅包含 ManufacturedParts
:
public class ManufacturedParts<T> : TCollection<T> where T : ManufacturedPart, new()
{
// Provide here some specific implementation related to ManufacturedParts
// if you want. For example, a TotalPrice property if ManufacturedPart
// has a Price property.
}
TCollection<ManufacturedPart> ss2 = new ManufacturedParts<ManufacturedPart>();
或者更简单,如果你的集合没有根据存储对象的类型提供任何额外的方法:
TCollection<ManufacturedPart> ss2 = new TCollection<ManufacturedPart>();
更简单的是,如果您的目标只是存储对象,则不需要自定义集合:
List<IdText> ss2 = new List<IdText>(); // Uses the built-in generic List<T> type
关于c# - 使用 IEnumerable<T> 创建通用集合的通用类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9235511/