C#指向List <t>(WinForms)</t>

时间:2014-01-21 15:32:54

标签: c# list pointers

我一直想知道如何正确地做到这一点,但我不完全确定。

我想创建一个用户名列表,并使用foreach循环将用户名绘制到屏幕上。用户名列表是一个静态列表,它将保存在MainClass中,绘图过程将在另一个类中进行(对于这个实例,我们将其称为Printer类)。

我的'问题'是我想要这样做,以便我不只是将那个List从MainClass复制到一个单独的List到Printer类中,所以当我从列表中添加/删除一个对象时,Printer类可以立刻告诉它已经改变了。

编辑:我不需要担心列表更改的事件,因为列表将打印在Paint事件上。我主要需要在Printer类中创建一个新变量,并在首次初始化类时将该变量与相关List“链接”

我不能简单地在打印机内部使用MainClass.usernameList,因为它将同时用于多个列表,复制MainClass列表只会为我提供一个永不更新的列表(除非我告诉它但是这可能会变得乏味有很多同时上课)。

我假设我需要使用指针,但我以前从未使用它们,并且整个不安全代码的想法似乎......不安全。

要点: 我需要在公共类中创建一个指向另一个类中的静态List的变量。

代码非常邋but但希望人们能够更好地了解我想要实现的目标:

enter image description here

4 个答案:

答案 0 :(得分:2)

我认为你的问题不应该以你的方式解决;无论如何,如果你使用 ObservableCollection ,你可以在列表中添加和删除元素时得到通知,然后你就可以做出反应。

此外,如果你的列表是静态的,你不需要传递引用,但如果你这样做,你仍然引用同一个对象,所以你总是有更新的列表。

答案 1 :(得分:1)

您可以将列表设为ObservableCollection<T>,然后在绑定到您的集合的CollectionChanged事件的其他类中实现逻辑。

因此,您只需将集合存储在有用的位置,然后在帮助程序类或控件中或您需要的任何位置实现CollectionChanged事件的事件处理程序。只要集合的内容发生变化,就会调用事件处理程序:

myCollection.CollectionChanged += SomeHelperClass.OnCollectionChanged;

并在您的助手班中编写

public void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // process e.NewItems
    ...

    // process e.OldItems
    ...
}

另见http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx

答案 2 :(得分:1)

您不需要不安全的阻止。默认情况下,所有对象都是引用,不会复制内容。

var x = new List<int>() { 1, 2, 3 };

var printer = new Printer();

// this assignment does not copy the list - it assigns the property to the same list
printer.UserList = x;

// verify that the reference was copied, not the data
x.Add(4);
printer.UserList.Add(5);

MessageBox.Show(x.Count.ToString()); // shows 5
MessageBox.Show(printer.UserList.Count.ToString()); // also shows 5

这是classstruct之间的主要区别。如果你有一个struct,那么它将被复制所有的整数,DateTime等变量。

答案 3 :(得分:0)

我没有看到任何人回答的方法可以让您倾听 List<T> 中发生的事情。

为此,您需要为列表创建一个基本的小包装器,其中至少包含一个您需要连接的EventHandler对象。

这是我刚刚聚集在一起的一个非常基本的实现:

public class SubscribeList<T> : IList<T> {

  private List<T> list;

  public EventHandler OnListContentsChange;

  public SubscribeList() {
    list = new List<T>();
  }

  public int IndexOf(T item) {
    return list.IndexOf(item);
  }

  public void Insert(int index, T item) {
    list.Insert(index, item);
    OnListContentsChange(this, EventArgs.Empty);
  }

  public void RemoveAt(int index) {
    list.RemoveAt(index);
    OnListContentsChange(this, EventArgs.Empty);
  }

  public T this[int index] {
    get {
      throw new NotImplementedException(); // do this if you want,
    }
    set {
      throw new NotImplementedException(); // but it is more complicated
    }
  }

  public void Add(T item) {
    list.Add(item);
    OnListContentsChange(this, EventArgs.Empty);
  }

  public void Clear() {
    list.Clear();
    OnListContentsChange(this, EventArgs.Empty);
  }

  public bool Contains(T item) {
    return list.Contains(item);
  }

  public void CopyTo(T[] array, int arrayIndex) {
    list.CopyTo(array, arrayIndex);
    OnListContentsChange(this, EventArgs.Empty);
  }

  public int Count {
    get { return list.Count; }
  }

  public bool IsReadOnly {
    get { return false; }
  }

  public bool Remove(T item) {
    var ok = list.Remove(item);
    if (ok) {
      OnListContentsChange(this, EventArgs.Empty);
    }
    return ok;
  }

  public IEnumerator<T> GetEnumerator() {
    foreach (var item in list) yield return item;
  }

  System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
    return list.GetEnumerator();
  }
}

现在,你这么说:

  

摘要:我需要在公共类中创建一个指向另一个类中的静态List的变量。

好的,让我们从另一个类中的静态List开始。不要笑:

public class AnotherClass {

  public static SubscribeList<String> List;

  static AnotherClass() {
    List = new SubscribeList<string>();
    List.OnListContentsChange += new EventHandler(List_ContentsChanged);
  }

  private static void List_ContentsChanged(object sender, EventArgs e) {
    Console.WriteLine("The contents of the list have changed! Call your Redraw Code.");
  }

}

必须连接OnListContentsChanged EventHandler,以便您的代码知道在列表更改时如何做出反应。

现在,要在指向此列表的公共类中创建变量,您可以执行以下操作:

public class PublicClass {

  private SubscribeList<String> list;

  public PublicClass() {
    list = AnotherClass.List;
  }

  private void someButton_Click(object sender, EventArgs e) {
    list.Add("Someone or txtName.Text from your form"); // this will fire the AnotherClass.List_ContentsChanged EventHandler.
  }

}

注意我创建了一个虚构的按钮点击事件,它将一个项目添加到您的静态列表中。

另外,请注意,如果AnotherClass中的列表从未创建过,那么您将在此处抛出异常。

如果那不是你想要的,那么我根本就不明白你的问题。