【发布时间】:2011-07-14 23:11:03
【问题描述】:
请随意质疑我的理智。
我需要确定 Action<T> 与 Action<T> 是否是原始实例。我所拥有的是一个带有类变量protected Action<T> MessageCallback = null; 的类,当我的abstract class Message<T> 是通过抽象方法创建时,我强制“它们”初始化MessageCallBack。此 MessageCallback 被添加到 IList<Action<object>>。此列表中定义的每个操作都可以不同。现在,我想做的是从列表中删除一个特定的操作,但我尝试比较它失败了。
以下是我上次尝试的设置示例:
public void Unsubscribe<TMessage>(Action<TMessage> messageCallback)
{
var messageType = typeof(TMessage);
var callbackTypes = messageReceivedCallbacks
.Keys
.Where(k => k.IsAssignableFrom(messageType));
lock (messageReceivedCallbacks)
{
foreach (var callbackType in callbackTypes)
{
messageReceivedCallbacks[callbackType].Remove(new Action<object>(m =>
messageCallback((TMessage)m)));
}
}
}
我知道我想做的事情可能是不可能的,但通常我只是在以不正当的方式做某事,或者缺乏适当的知识来按照我的假设去做。提前感谢您提供的任何帮助。
- 尝试以下一些方法后更新:
比较它们总是失败。目前以下 3 条建议均无效。我确实相信我可以改变我处理这个问题的方式,并通过传递一个带有操作的键,然后指向<key, indexOfAction> 的单独列表然后按索引删除它来使它按我需要的方式工作。但是,我觉得我仍然需要付出很大的努力来解决,所以我将提供更多信息,看看它是否有帮助。
这里是列表:
private readonly IDictionary<Type, IList<Action<object>>> messageReceivedCallbacks;
下面是如何将动作添加到列表中:
void AddMessageReceivedCallback<TMessage>(Action<TMessage> messageReceivedCallback)
{
var intermediateReceivedCallback = new Action<object>(m =>
messageReceivedCallback((TMessage)m));
var receivedList = messageReceivedCallbacks.GetOrCreateValue(typeof(TMessage),
() => new List<Action<object>>());
lock (receivedList)
{
receivedList.Add(intermediateReceivedCallback);
}
}
请多多包涵,因为我对一些更高级的编码比较陌生。由于new 关键字,我可以说这阻止了我进行直接实例比较。在我(第一次)在上面发布的尝试中,我试图让我的回调与添加它的形式相匹配。这没用。我尝试比较目标、方法,甚至将它们转换为其他类型,然后进行比较。
我决定将我传递的回调转换为添加到最后一个 aka 的相同方式:
var callbackConverted = new Action<object>(m =>
messageReceivedCallback((TMessage)m));
接下来,我使用即时窗口来获取一些信息(callback 是列表中的那个,callbackConverted 是我传入的那个):
callback.Target
{MessageBus.MessageCoordinator.<Tests.MessageBus.TestMessage>}
messageReceivedCallback: {Method = {Void <InitializeMessageCallback>b__0(Tests.MessageBus.TestMessage)}}
callback.Method
{Void <AddMessageReceivedCallback>b__8(System.Object)}
[System.Reflection.RuntimeMethodInfo]: {Void <AddMessageReceivedCallback>b__8(System.Object)}
base {System.Reflection.MethodBase}: {Void <AddMessageReceivedCallback>b__8(System.Object)}
MemberType: Method
ReturnParameter: {Void }
ReturnType: {Name = "Void" FullName = "System.Void"}
ReturnTypeCustomAttributes: {Void }
callbackConverted.Target
{MessageBus.MessageCoordinator.<Tests.MessageBus.TestMessage>}
messageReceivedCallback: {Method = {Void <InitializeMessageCallback>b__0(Tests.MessageBus.TestMessage)}}
messageType: {Name = "TestMessage" FullName = "Tests.MessageBus.TestMessage"}
callbackConverted.Method
{Void <Unsubscribe>b__1d(System.Object)}
[System.Reflection.RuntimeMethodInfo]: {Void <Unsubscribe>b__1d(System.Object)}
base {System.Reflection.MethodBase}: {Void <Unsubscribe>b__1d(System.Object)}
MemberType: Method
ReturnParameter: {Void }
ReturnType: {Name = "Void" FullName = "System.Void"}
ReturnTypeCustomAttributes: {Void }
我希望这些附加信息对您有所帮助。
- **更新
我发现我把它弄得太复杂了。我需要做的就是添加我的操作,然后从每个字典中删除(它的唯一实例)。我正在竭尽全力做一些复杂的事情。
目前没有提供我可以说肯定有效的方法,但我正在标记我认为其他人最有可能使用的方法作为答案。感谢所有贡献的人。
【问题讨论】:
-
那么,您正在尝试从现有的可枚举中删除“新”对象?
-
messageReceivedCallbacks 是什么类型的?请将
var更改为特定类型。 -
@jwJung:来吧,这显然是
IDictionary<Type, IList<Action<object>>>或者没有I的... -
@Timewi:你是对的!你赢得了良好的感觉。
标签: c# generics delegates comparison