我有一个类似这样的课程:
public static class Messenger<T>
{
private static readonly Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();
public static void DoSomethingWithEventTable() //Somehow fills eventTable
public static void Clear()
{
eventTable.Clear();
}
}
现在,我在程序的某个地方打了两次DoSomethingWithEventTable
,就像这样:
Messenger<int>.DoSomethingWithEventTable();
Messenger<float>.DoSomethingWithEventTable();
我想清除每个eventTable
的{{1}}。我该怎么办?我应该为我在泛型中输入的每种类型调用Messenger<T>
,如下所示:
Clear
或者只做一次这样愚蠢的事情就足够了:
Messenger<int>.Clear();
Messenger<float>.Clear();
UPD:基本实验表明我应该清除所有使用过的T的Messenger。现在有人可以为这些课程设计更好的设计吗?
我现在使用的更详细的版本:
Messenger<string>.Clear();
同样重要的是,我有另一个班级static public class Messenger<T>
{
private static readonly Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();
static public void AddListener(string eventType, Callback<T> handler)
{
// Obtain a lock on the event table to keep this thread-safe.
lock (eventTable)
{
// Create an entry for this event type if it doesn't already exist.
if (!eventTable.ContainsKey(eventType))
{
eventTable.Add(eventType, null);
}
// Add the handler to the event.
eventTable[eventType] = (Callback<T>)eventTable[eventType] + handler;
}
}
static public void RemoveListener(string eventType, Callback<T> handler)
{
// Obtain a lock on the event table to keep this thread-safe.
lock (eventTable)
{
// Only take action if this event type exists.
if (eventTable.ContainsKey(eventType))
{
// Remove the event handler from this event.
eventTable[eventType] = (Callback<T>)eventTable[eventType] - handler;
// If there's nothing left then remove the event type from the event table.
if (eventTable[eventType] == null)
{
eventTable.Remove(eventType);
}
}
}
}
static public void Invoke(string eventType, T arg1)
{
Delegate d;
// Invoke the delegate only if the event type is in the dictionary.
if (eventTable.TryGetValue(eventType, out d))
{
// Take a local copy to prevent a race condition if another thread
// were to unsubscribe from this event.
Callback<T> callback = (Callback<T>)d;
// Invoke the delegate if it's not null.
if (callback != null)
{
callback(arg1);
}
}
}
static public void Clear()
{
eventTable.Clear();
}
}
(非通用,是的)和Messenger
,也许有一天我甚至需要Messenger<T,M>
等等。
答案 0 :(得分:3)
每个Messenger<T>
类型都有自己的eventTable副本,因此您需要为您使用的每个不同的T调用Clear()。
如本测试所示:
[TestFixture]
public class Tests
{
static class MyClass<T>
{
public static List<int> Member = new List<int>();
}
[Test]
public void StaticTest()
{
var m1 = MyClass<int>.Member;
var m2 = MyClass<string>.Member;
Assert.AreNotSame(m1, m2);
}
}
答案 1 :(得分:3)
自
private static readonly Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();
不依赖<T>
,为所有事件表创建静态“处理程序”。
IE
public static class TableHandler {
ICollection<Dictionary<string, Delegate>> tables = new List<Dictionary<string, Delegate>>();
public void Add(Dictionary<string, Delegate> item)
{
tables.Add(item);
}
public void Clear()
{
foreach (var item in tables) item.Clear();
tables.Clear();
}
}
并确保DoSomethingWithEventTable()
将事件表添加到TableHandler
。
可能不是最好的整体解决方案,但它可以帮助您跟踪当前设计的表格。
修改强>
我试图谷歌寻找静态类的所有通用变体,但我找不到方法。有谁知道这样做的方法?