Не стесняйтесь задавать вопросы о моем здравомыслии.
Мне нужно определить, является ли 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 }
Надеюсь, эта дополнительная информация поможет.
Я понял, что делал это слишком сложно. Все, что мне нужно было сделать, - это добавить свое действие, а затем удалить (единственный его экземпляр) из каждого словаря. Я старался изо всех сил делать что-то сложное.
В настоящее время метод не предусмотрен, я могу сказать, что он работает точно, но я отмечаю тот, который, по моему мнению, лучше всего использовать в качестве ответа. Спасибо всем, кто внес свой вклад.