Пожалуйста, помогите мне с этим вопросом. Я кодирую систему способностей в Unity3D 2019.4.1 (если вы хотите знать) и создал класс «Roller» для некоторых случайных чисел. Есть
public static Func<Creature, int> OnNumberRolled;
в классе "Ролик". Некоторые способности в моей игре должны знать об этих случайных числах, и когда они выбрасываются, они вызывают некоторую путаницу. Вот класс способностей:
public class ListenerEffect : Effect
{
public int OnRolledOne(Creature creature)
{
...
}
public override void CastEffect(ITargetable caster, ITargetable target)
{
Creature localCasterCreature = caster as Creature;
Roller.OnNumberRolled += OnRolledOne(localTargetCreature);
}
}
В данный момент
Roller.OnNumberRolled += OnRolledOne(localTargetCreature);
возникает ошибка. В нем говорится, что он не может преобразовать «int» в «System.Func<Creature, int>». Оба класса используют System. Что я должен делать?
В вашем примере OnRolledOne(localTargetCreature)
выполнит функцию и вернет и int. Вот почему вы не можете назначить его OnNumberRolled, который ожидает Func<Create,int>.
Просто используйте имя функции. В противном случае вы вызываете функцию и используете возвращаемое значение.
Roller.OnNumberRolled += OnRolledOne;
Если вы добавите несколько обработчиков, имейте в виду, что возвращаемые значения будут потеряны (но последнее) при вызове как OnNumberRolled()
.
У вас могут быть обработчики для добавления своих результатов в список или что-то в этом роде, но нам потребуется больше информации о ваших вариантах использования, чтобы разработать удовлетворительное решение.
Вы также можете перебирать обработчики следующим образом:
var handlers = OnNumberRolled.GetInvocationList();
foreach (var handler in handlers)
{
// invoke and handle each handlers'result here
Debug.Log(handler());
}
Хммм... Я хочу активировать несколько вещей из одного события. Я думаю, что Roller.OnNumberRolled = OnRolledOne
перезапишет другую логику. Есть ли способ сделать это?
Вы можете использовать +=
. Это называется состав делегата
Иш. Ваш делегат возвращает int
. Если вы создаете делегата многоадресной рассылки с помощью +=
, все возвращаемые значения, кроме значения от последнего вызываемого делегата, теряются.
@MrWatchmanLP Я добавил версию delegate
/ event
, но да, имейте в виду комментарий canton7. Например, вы можете захотеть, чтобы ваши обработчики событий добавляли результат в какой-то список, но это может очень быстро превратиться в спагетти-код.
Спасибо всем, ребята. Это мне очень помогло!
@EmanuelVintilă да, действительно, но нужно использовать делегатов, а не только System.Func
, я обновил свой ответ.
@Pac0 System.Func
— тип делегата
@EmanuelVintilă Ха, спасибо. Теперь я чувствую себя тупым, не замечая этого так долго ... снова отредактировал ответ.
Пожалуйста, прочитайте о событиях в C# и о том, как они работают.