Проблема отражения C #: Как спросить класс, если у него есть объект с именем - PullRequest
0 голосов
/ 04 мая 2009

У меня есть несколько экземпляров класса в моем коде, каждый из которых имеет различные конфигурации и т. Д. В этом классе есть метод обработчика событий делегата, который получает событие от отправителя и затем должен выполнить какое-то действие с одним из указанных выше объектов.

Я хотел бы знать, может ли отражение решить эту проблему.

private CatClass cat1;
private CatClass cat2;
private CatClass cat3;

Я бы хотел не проверять каждый экземпляр независимо, чтобы увидеть, нужен ли мне этот объект. Но вместо этого он хотел бы каким-то образом получить экземпляр объекта, который идентифицировал отправляющее событие.

Итак

private void delegateHandler(string senderName, object sender, CustomEventType evt)
{
     // given reciept of the senderName string,
     // how do I perform an action on say the cat2 object

    // Is it possible to ask the class if it has an object defined
    // called 'cat2' and then proceed with performing an action on that object
}    

Спасибо за помощь.

Ответы [ 6 ]

1 голос
/ 04 мая 2009

Это очень маловероятно, чтобы достичь того, что вы хотите? Из любопытства отправитель не даст вам подходящий экземпляр? Если нет, то вы должны поместить экземпляры выстрелов CatClass в словарь и при необходимости выполнить поиск в этом словаре.

0 голосов
/ 03 октября 2012

Существуют разные способы решения этой проблемы. Отражение, конечно, не правильный выбор.

Один из подходов - использовать массив кошек

Cat[] cats = new Cat[] { new Cat(), new Cat(), new Cat() };

Вместо работы с именами кошек вы будете работать с номерами кошек

private void delegateHandler(int catNumber, object sender, CustomEventType evt)
{
    DoSomethingWith(cats[catNumber]);
}

Еще один способ - передать самого кота как отправителя (это обычный способ работы с обработчиками событий)

private void delegateHandler(object sender, CustomEventType evt)
{
    Cat cat = (Cat)sender;
    DoSomethingWith(cat);
}

Еще один способ - присвоить каждой кошке имя свойства

public class Cat
{
    public string Name { get; set; }

    // Other properties and methods       
}

затем используйте словарь для хранения кошек

var catsByName = new Dictionary<string, Cat>();
Cat cat = new Cat { Name = "Tiger" };
catsByName.Add(cat.Name, cat);
...

Тогда вы можете получить кошку по имени

cat = catsByName["Tiger"];

Или, если вы не уверены, существует ли кошка

if (catsByName.TryGetValue("Misty", out cat)) {
    DoSomethingWith(cat);
} else {
    CatNotFound();
}
0 голосов
/ 03 октября 2012

Я сомневаюсь, что вас это даже волнует, но на ваш конкретный вопрос о том, как решить эту проблему, ответ так и не был дан. Вот в основном, как бы вы это сделали.

private void delegateHandler(string senderName, object sender, CustomEventType evt)
{
    FieldInfo field = this.GetType().GetField(senderName, BindingFlags.NonPublic | BindingFlags.Instance);
    if(field != null && field.Name == senderName)
    {
        CatClass cat = (CatClass)field.GetValue(this);
        cat.DoWork();
    }
}
0 голосов
/ 04 мая 2009

Ну, как и вышеупомянутые посты, Reflection вообще плохая идея.

this.GetType().GetMember(senderName) == null;

Вероятно, сработало бы и здесь.

0 голосов
/ 04 мая 2009

Вы можете использовать отражение для этого, но я бы посоветовал не делать этого. Отражение медленное, и это маловероятно, когда это требуется.

Почему бы не иметь словарь (если вы хотите найти их по имени), список или массив CatClass и итерировать их, чтобы увидеть, какой из них вам нужен?

0 голосов
/ 04 мая 2009

C # работает лучше, если вы «говорите», а не когда «спрашиваете».

Другими словами, было бы лучше иметь интерфейс или базовый класс, в котором объявлен член CatClass, который позволил бы вам работать с переменной этого типа интерфейса или базового класса вместо использования отражения. Единственное, что меня беспокоит, так это то, что члены, которые вы надеетесь использовать, являются частными, это не позволит вам использовать интерфейс.

Вы действительно используете обработчик, который копается в отправителя через рефлексию для извлечения приватных членов? Возможно, вам следует переосмыслить свой подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...