c# - 在不知道 T 的情况下保留 List<T> 的引用?

标签 c# unity-container

澄清:目标是让我的 UIPList 1.能够观察任何 ObservableList,其中 T 是 iUIP 或其继承者之一,2.能够在列表,以及 3. 能够随时更改正在观看的列表(并且只能观看一个列表)。

我可以绘制 gui 按钮并让第一只 watch 正常工作(使用下面的 hacky 代码),但是无法将引用存储在 UIPList 中,因此当我想观看其他内容时我可以从该列表中取消订阅。我不能在不失去上面提到的第三种能力的情况下将它变成“UIPList”(这将使存储引用成为可能)。

我现在正在尝试让菜单(谁知道涉及什么 UIPLists 和 ObservableLists)在内容更改时处理取消订阅,但理想情况下我可以将 ObservableList 传递给 UIPList,它会知道如何观看它,绘制图形用户界面,并在它获得新列表时取消订阅。

原帖: 我有UIPList应该看ObservableList<T> where T:iUIP . ( iUIP 表示具有可以在 UIPList 中绘制的按钮的类)。

问题是我无法存储对列表的本地引用,因为它可能是 ObservableList<iUIP>或者它可以是 ObservableList<Character>或者 ObservableList<Organization>等等(其他类继承 iUIP )。

我不能使用 ObservableList<iUIP>UIPList作为引用,因为我可能想观看无法转换为 ObservableList<iUIP> 的列表尽管字符继承自 iUIP,因此无法存储对列表 UIPList 的本地引用应该观看。

我使用 SetWatchList<T>(ObservableList<T> list) UIPList 上的方法拿一个列表来观看,但由于没有引用原始列表,当我想更改 UIPList 的内容时正在观看我没有引用资料,我需要取消订阅上一个列表。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//using System.Collections.ObjectModel;

public class UIPList : MonoBehaviour
{
public GUIManager GUIManager;
public UILabel Title;
public UITable Contents;

//  ObservableList<T>.ListChangedEventHandler subscribedChangeEvent;

public void WatchList<T>(ObservableList<T> list) where T: iUIP
{
    this.subscribedChangeEvent = list.ListChanged;
    list.ListChanged += DrawUIPList;//TODO make always clear prev?
    DrawUIPList<T>(list);
}

//dont have a reference to the old list to know what to stop watching!
//  public void StopWatchList<T>(ObservableList<T> list) where T: iUIP
//  {
//      list.ListChanged -= DrawUIPList;
//  }

// Use this for initialization
protected void Start()
{
    this.GUIManager = GUIManager.Find;
}
// Update is called once per frame
void Update()
{
}


void DrawUIPList<T>(object source, ObservableList<T>.ListChangedEventArgs e) where T : iUIP
{
    DrawUIPList<T>(e.list);
}
void DrawUIPList<T>(ObservableList<T> list) where T:iUIP
{
    //todo AddComponentMenu/RemoveItem/adjut ReadOnlyCollectionBase changed UIPs
    ClearContents();
    this.Contents.Reposition();
    foreach (T uip in list)//TODO make this automatic, not need each one
    {
        //          Debug.Log("Adding UIP:" + child.name);
        if (uip.UIPButton is UIPCorporationButton)
            UIPCorporationButton.Create(this.Contents.gameObject, (uip as Corporation));

        if (uip.UIPButton is UIPCompanyButton)
            UIPCompanyButton.Create(this.Contents.gameObject, (uip as Company));

        if (uip.UIPButton is UIPAssetButton)
            UIPAssetButton.Create(this.Contents.gameObject, (uip as Asset));

        if (uip.UIPButton is UIPIndButton)
            UIPIndButton.Create(this.Contents.gameObject, (uip as Industry));

        if (uip.UIPButton is UIPSecButton)
            UIPSecButton.Create(this.Contents.gameObject, (uip as Sector));

        if (uip.UIPButton is UIPOperativeButton)
            UIPOperativeButton.Create(this.Contents.gameObject, (uip as Operative));

        if (uip.UIPButton is UIPAgencyButton)
            UIPAgencyButton.Create(this.Contents.gameObject, (uip as Agency));

        if (uip.UIPButton is UIPBrokerButton)
            UIPBrokerButton.Create(this.Contents.gameObject, (uip as Broker));

        if (uip.UIPButton is UIPCellButton)
            UIPCellButton.Create(this.Contents.gameObject, (uip as Cell));

        if (uip.UIPButton is UIPMissionButton)
            UIPMissionButton.Create(this.Contents.gameObject, (uip as Mission));

        if (uip.UIPButton is UIPObjectiveButton)
            UIPObjectiveButton.Create(this.Contents.gameObject, (uip as Objective));

        if (uip.UIPButton is UIPChallengeButton)
            UIPChallengeButton.Create(this.Contents.gameObject, (uip as Challenge));


    }
    //this.Contents.Reposition();
    this.Contents.repositionNow = true;
}

public void ClearContents()
{
//      this.Contents.children.children.Clear();
    int count = this.Contents.transform.childCount;     
    for (int i = count - 1; i >= 0; i--)
    {           
        GameObject.Destroy(this.Contents.transform.GetChild(i).gameObject);         
    }
}
}

最佳答案

使整个类通用

public class UIPList<T> : MonoBehaviour where T : iUIP

然后您可以存储对列表的引用。这更好地封装了列表的实际内容。

不要忘记也从您的方法中删除通用约束

public void WatchList(ObservableList<T> list)

关于c# - 在不知道 T 的情况下保留 List<T> 的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21566253/

相关文章:

c# - 我无法捕捉到异常

c# - MVVM Light + Unity 还是 Prism?

entity-framework - 使用 Unity,您如何自动处理 IDisposable?

c# - 如何在 PRISM 模块中使用 ReactiveUI

c# - 如何设置 Unity 3 以在控制台应用程序中工作?

c# - MVC 5 和 Unity IoC 中的 AccountController

c# - MySQL 的连接字符串(asp.net 中的 C#)

c# - 无法将泛型列表作为参数发送到 WCF 方法

c# - 在不复制源列表的情况下高效地对 IList<T> 进行排序

c# 同时在 cmd.exe 中运行多个命令并将输出写入文本文件