我试图通过将列表“合并”到一个新的类中来使其更加用户友好,但是从新的类中访问列表的特定功能和属性会给我带来麻烦。
下面是一个例子:
public class Words : List<Word>
{
public uint BytesPerWord { get; protected set; }
public Word this[int index] => this.ElementAt(index);
/* public new Words GetRange(int index, int count)
{
var a = this.GetRange(index, count);
return a;
}*/
public Words(uint bytesPerWord) : base()
{
BytesPerWord = bytesPerWord;
}
}
现在,我试着从别处提取一些“words”类型的单词,通过这样做,把它们的一部分提取到我的单词中:
Words myWords = someOtherWords.GetRange((int)X, (int)Y);
这里有几个问题:
我们非常感谢您提出如何修复此问题的任何建议。
请注意,我还尝试用集合替换List,因为我已经读过“我不应该从List派生”,但这并没有什么区别。
根据经验,您不应该从list
派生; 它有很多你可能不想继承的行为。
为了避免重蹈覆辙,您可以通过组合使用list<;t>
:
public class Words
{
private readonly List<Word> _list; // Composition
public uint BytesPerWord { get; protected set; }
public Word this[int index] => _list[index];
public Words GetRange(int index, int count)
{
var a = _list.GetRange(index, count);
return new Words(BytesPerWord, a);
}
public Words(uint bytesPerWord) : this(bytesPerWord, new List<Word>()) { }
private Words(uint bytesPerWord, List<Word> list)
{
BytesPerWord = bytesPerWord;
_list = list;
}
}
如果需要类是可枚举的,甚至可以实现IEnumerable
:
public class Words : IEnumerable<Word>
{
private readonly List<Word> _list;
//...
public IEnumerator<Word> GetEnumerator() => _list.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
这同样适用于其他集合接口。
您的代码无法工作,因为您在方法GetRange中调用this.GetRange(而不是base.GetRange),这将创建一个无限循环,直到发生stackoverflow异常。
因此您可以将代码更改为
public class Words : List<Word>
{
public uint BytesPerWord { get; protected set; }
public new Word this[int index] => this.ElementAt(index);
public new Words GetRange(int index, int count)
{
var a = base.GetRange(index, count);
Words copy = new Words(100);
copy.AddRange(a);
return copy;
}
然而,我有点困惑,这将如何帮助您的代码的可读性。 如果您不需要向列表
添加任何新功能,那么我认为隐藏变量的真实性质不是一个好主意。
还要注意这一行:
public Word this[int index] => this.ElementAt(index);
可以在新修饰符之前编写,并可选地引用基类
public new Word this[int index] => base[index];
反对这个类有用的另一个原因。