c# - 如何克隆列表的一部分?

标签 c# .net list clone

是否可以仅克隆 List<T> 的一部分?

示例:

List<string> myoriginalstring = new List<string>();
myoriginalstring.Add("Tyrannosaurus");
myoriginalstring.Add("Amargasaurus");
myoriginalstring.Add("Mamenchisaurus");

我想克隆myoriginalstring到另一个列表,但仅来自索引 1到索引2 .

这可能吗?第二个变化List<string>应该首先体现出来,反之亦然。

更新

感谢您迄今为止的回答。看来我没有正确表达自己的意思。

其实我不想复制或克隆。我需要创建一个新列表(这将是原始列表的一部分);当我更改新列表中的某些内容(某些值)时,原始列表也应该以相同的方式更改。 (列表应该始终相同,只是新列表将是原始列表的一部分)。

希望这更清楚。

最佳答案

您可以创建 ListSlice<T>表示现有列表的一部分的类。该切片将充当只读列表,并且因为它保留对原始列表的引用,所以您不应该在原始列表中添加或删除元素。除非您实现自己的列表,否则无法强制执行此操作,但我不会在这里这样做。

您必须实现整个IList<T>界面包括 IEnumerator<T>您需要枚举切片。这是一个例子:

class ListSlice<T> : IList<T> {

  readonly IList<T> list;

  readonly Int32 startIndex;

  readonly Int32 length;

  public ListSlice(IList<T> list, Int32 startIndex, Int32 length) {
    if (list == null)
      throw new ArgumentNullException("list");
    if (!(0 <= startIndex && startIndex < list.Count))
      throw new ArgumentException("startIndex");
    if (!(0 <= length && length <= list.Count - startIndex))
      throw new ArgumentException("length");

    this.list = list;
    this.startIndex = startIndex;
    this.length = length;
  }

  public T this[Int32 index] {
    get {
      if (!(0 <= index && index < this.length))
        throw new ArgumentOutOfRangeException();
      return this.list[this.startIndex + index];
    }
    set {
      if (!(0 <= index && index < this.length))
        throw new ArgumentOutOfRangeException();
      this.list[this.startIndex + index] = value;
    }
  }

  public Int32 IndexOf(T item) {
    var index = this.list.IndexOf(item);
    return index == -1 || index >= this.startIndex + this.length
      ? -1 : index - this.startIndex;
  }

  public void Insert(Int32 index, T item) { throw new NotSupportedException(); }

  public void RemoveAt(Int32 index) { throw new NotSupportedException(); }

  public Int32 Count { get { return this.length; } }

  public Boolean IsReadOnly { get { return true; } }

  public void Add(T item) { throw new NotSupportedException(); }

  public void Clear() { throw new NotSupportedException(); }

  public Boolean Contains(T item) { return IndexOf(item) != -1; }

  public void CopyTo(T[] array, Int32 arrayIndex) {
    for (var i = this.startIndex; i < this.length; i += 1)
      array[i + arrayIndex] = this.list[i];
  }

  public Boolean Remove(T item) { throw new NotSupportedException(); }

  public IEnumerator<T> GetEnumerator() {
    return new Enumerator(this.list, this.startIndex, this.length);
  }

  IEnumerator IEnumerable.GetEnumerator() {
    return GetEnumerator();
  }

  class Enumerator : IEnumerator<T> {

    readonly IList<T> list;

    readonly Int32 startIndex;

    readonly Int32 length;

    Int32 index;

    T current;

    public Enumerator(IList<T> list, Int32 startIndex, Int32 length) {
      this.list = list;
      this.startIndex = startIndex;
      this.length = length;
    }

    public T Current { get { return this.current; } }

    Object IEnumerator.Current {
      get {
        if (this.index == 0 || this.index == this.length + 1)
          throw new InvalidOperationException();
        return Current;
      }
    }

    public Boolean MoveNext() {
      if (this.index < this.length) {
        this.current = this.list[this.index + this.startIndex];
        this.index += 1;
        return true;
      }
      this.current = default(T);
      return false;
    }

    public void Reset() {
      this.index = 0;
      this.current = default(T);
    }

    public void Dispose() {
    }

  }

}

您可以编写扩展方法来更轻松地使用切片:

static class ListExtensions {

  public static ListSlice<T> Slice<T>(this IList<T> list, Int32 startIndex, Int32 length) {
    return new ListSlice<T>(list, startIndex, length);
  }

}

要使用切片,您可以编写如下代码:

var list = new List<String> {
  "Tyrannosaurus",
  "Amargasaurus",
  "Mamenchisaurus"
};
var slice = list.Slice(1, 2);
slice[0] = "Stegosaurus";

现在list[1]以及 slice[0]包含"Stegosaurus" .

关于c# - 如何克隆列表的一部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26495500/

相关文章:

C# 它们是相同的 : Encoding. UTF8.GetBytes 和 Convert.FromBase64String 吗?

c# - 很难找到在正则表达式中插入 "word exclusion"的位置

c# - Alchemy-Websockets - WebSocketClient 路径

asp.net - WCF 服务调用仅在 Fiddler 运行时有效

.net - 是否有任何登录 ReSharper 以找出测试不确定的原因?

list - Scala 获取列表中小于特定值的所有元素

mysql - rails 将新元素添加到列表中的特定位置(上方或下方)

c# - 从 ItemsControl 中的模板获取项目

java - 如何在 LinkedList 实现中的指定索引处添加节点

c# - 如果错误记录在脚本中,PlayMode 测试默认停止