ChrisCross
ChrisCross

Reputation: 101

Nested interface not calling childs method when return is of type T

So I was trying to get more familiar with interfaces and I thought it could be a cool idea to use nested interfaces to seperate parts of the logic so I have these interfaces:

public interface ISortedGroupWithMover<T>: ISortedGroup<IMoveableHoldee<T>>
public interface ISortedGroup<T> : IGroup<T>
public interface IGroup<T>
public interface IMoveableHoldee<T> : IHoldee<T>, IHoldeeMovements<T>
public interface IHoldeeMovements<T>
public interface IHoldee<T>

So these were the interfaces I came up with, its basically like two interfaces that are just a bit more layered.

First one is The group -> sorted group -> sortedgroupmover

second one is holdee -> moveableHoldee (which is a holdee that can use the movements)

in general this seemed to work, and I mean i could put most of it in like a same interface but I wanted to play around a bit and thought it would be better if different parts of the logic is seperated.

Now the problem that occured was as follows:

I have the class:

public class CardDeck : MonoBehaviour, ISortedGroupWithMover<ACardFather>

The main idea is to have a deck which is a sorting group that has elements that can move

it implements the:

(from: public interface IGroup<T>)
public List<T> GetHoldees();

as

public List<IMoveableHoldee<ACardFather>> GetHoldees() => _cards;
var deck = DealDeck().GetHoldees().First().IHoldee.GetGameObject().name;

now this is a bit deep but this (Iholdee is just the class casted) returns the correct card in the deck and actually works

however the issue arises when I try to use the method

(from:     public interface ISortedGroup<T> : IGroup<T>)
public T TopHoldee() => GetHoldees().First();

now this is a method that has a body which might be another reason of the misbehaving

The real weird part is that this method is NEVER ran, even if I call it and put a print in the method body it will NOT print

Now if I change this method with the following:

public void TopHoldee()
{
    Debug.Log("TTEST: " + GetHoldees().First());
}

This prints the correct element

This is a unity project so that could also have something to do with it, but im kinda confused by the fact that the just changing the type can have this effect. I also dont have any idea why this is the case so please let me know whats the cause of this unexpected behaviour.

Note:

public abstract class ACardFather : MonoBehaviour, SortedUiObject, IMoveableHoldee<ACardFather>

this is the cardfather class

public interface IGroup<T>
    {
        public RectTransform GetRect() => GetHolder().GetComponent<RectTransform>();
        public GameObject GetHolder();
        public List<T> GetHoldees();
    }
public interface ISortedGroupWithMover<T>: 
    ISortedGroup<IMoveableHoldee<T>>
    {
    bool IsMoving { get; set; }
    void StartMoving() => IsMoving = true;
    void EndMoving() => IsMoving = false;

    bool IsBottomCollapsed();
    bool IsTopCollapsed();
    }
 public interface IMoveableHoldee<T> : IHoldee<T>, 
    IHoldeeMovements<T>
    {
        IHoldee<T> IHoldee => this;
        IHoldee<T> IMovements => this;
    }

public interface ISortedGroup<T> : IGroup<T>
    { 
        public int GetVerticalOffset();
        public int GetHorizontalOffset();
        public bool ExemptFirst();
        public Vector3 GetOffset(int order)
        {
        ...
        }
private void ChangeOffsets(int order, MonoBehaviour obj)
        {            
           ...
        }
private void ChangeSortingOrder(int order, SortedUiObject 
    sortedObj)
        {...

        }
private void ChangeSizes(MonoBehaviour card)
        {
            ...
        }
public IEnumerator MoveToStartingPos(float 
    duration,AnimationCurve curve)
        {
           ...
        }
        public T TopHoldee() => GetHoldees().Last();
        public T BottomHoldee() => GetHoldees().First();
        
        
    }

This should be all the necessary classes

Edit: I just tried this print:

    Debug.Log("BottomItem is: " +d.BottomItem());
    Debug.Log("TopItem is:" +d.TopItem());

for the methods set to:

        public T TopItem() => GetHoldees().First();
        public T BottomItem() => GetHoldees().First();
        BottomItem is: System.Collections.Generic.List`1[DefaultNamespace.IMoveableHoldee`1[ACardFather]]

        TopItem is:tmpdeck (UnityEngine.GameObject)

i am so confused by this debug log

Upvotes: 0

Views: 40

Answers (1)

ChrisCross
ChrisCross

Reputation: 101

    public interface ISortedGroupWithMover<T> : ISortedGroup<T>
        where T : IMoveableHoldee<T>

I think the correct interface for this is like this, I dont think the previous version has the same meaning altough im not sure of the difference.

EDIT: The issues still arise, its very random and unpredictable:

        public T BottomHoldee() => GetHoldees().First();
        public T TopHoldee() => GetHoldees().Last();

these methods inside the ISortedGroup is the reason for the crash it sometimes returns a List of T instead of the T itself im not sure why tho

They seem to work when put inside IGroup, however like I said its random so it might not work at some point. If anyone has any idea why this issue occurs please let me know.

Upvotes: 0

Related Questions