Как получить из eventData.pointerDrag конкретный класс? А также как сократить ифы и элсы?

У меня есть два класса: ItemAmmunition и ItemConsumables. Они оба работают +- одинаково, однако их главное отличие - ItemAmmunition может помещаться в MainCell и AmmunitionCell, а ItemConsumables только в MainCell. И отсюда начинаются все проблемы!

Нерабочий код в MainCell-е.

public void OnDrop(PointerEventData eventData)
{
    var a = eventData.pointerDrag.GetComponent<ItemConsumables>();
    if (eventData.pointerDrag.GetComponent<ItemConsumables>() != null)
        a = eventData.pointerDrag.GetComponent<ItemConsumables>();
    else
        a = eventData.pointerDrag.GetComponent<ItemAmmunition>();

    if (CheckCellFree(this, a.size))
    {
        a.prevMainCell = this;

        a.SetPosition(a.gameObject, this, null);
        CellOccupation(this, false, dragItem.size);
    }
    else
    {
        dragItem.SetPosition(dragItem.gameObject, dragItem.prevMainCell, null);
        CellOccupation(dragItem.prevMainCell, false, dragItem.size);
    }
} 

Я не могу даже нормально узнать, что там содержится, и написать это! Если я буду делать этот код так (Первый, но уже исправленный мною код.):

public void OnDrop(PointerEventData eventData)
{

    if (eventData.pointerDrag.GetComponent<ItemConsumables>() != null)
    {
        var a = eventData.pointerDrag.GetComponent<ItemConsumables>();
        if (CheckCellFree(this, a.size))
        {
            a.prevMainCell = this;

            a.SetPosition(a.gameObject, this, null);
            CellOccupation(this, false, a.size);
        }
        else
        {
            dragItem.SetPosition(a.gameObject, a.prevMainCell, null);
            CellOccupation(a.prevMainCell, false, a.size);
        }
    }
    else
    {
        var a = eventData.pointerDrag.GetComponent<ItemAmmunition>();
        if (CheckCellFree(this, a.size))
        {
            a.prevMainCell = this;

            a.SetPosition(a.gameObject, this, null);
            CellOccupation(this, false, a.size);
        }
        else
        {
            dragItem.SetPosition(a.gameObject, a.prevMainCell, null);
            CellOccupation(a.prevMainCell, false, a.size);
        }
    }
}

То выходит вообще длинно! Я бьюсь с этим уже очень долго. Как сокращать эти if-else-ы, и как вообще присваивать вот такие переменные? Не хочется выдумывать велосипеды.


Ответы (1 шт):

Автор решения: aepot

Как я понял, речь про второй кусочек кода. Вам надо почитать про обобщения (generic).

Но для того чтобы обобщить, нужно чтобы классы ItemConsumables и ItemAmmunition имели общего наследника или реализовывали общий интерфейс, имеющий публичные члены, которые вам требуются.

Так как классов не вижу, а типы по коду не понять, не смогу описать интерфейс точно. Думаю, сможете дополнить самостоятельно.

public interface IItem
{
    public ... prevMainCell;
    public ... SetPosition(...);
    public ... gameObject;
    public ... size;
}

Далее указать, что классы реализуют этот интерфейс

public class ItemConsumables : MonoBehavior, IItem
{
    // ...
}

public class ItemAmmunition : MonoBehavior, IItem
{
    // ...
}

Получится как-то так

public void OnDrop(PointerEventData eventData)
{
    IItem a = eventData.pointerDrag.GetComponent<ItemConsumables>();
    if (a == null)
        a = eventData.pointerDrag.GetComponent<ItemAmmunition>();

    if (CheckCellFree(this, a.size))
    {
        a.prevMainCell = this;

        a.SetPosition(a.gameObject, this, null);
        CellOccupation(this, false, dragItem.size);
    }
    else
    {
        dragItem.SetPosition(dragItem.gameObject, dragItem.prevMainCell, null);
        CellOccupation(dragItem.prevMainCell, false, dragItem.size);
    }
} 
→ Ссылка