Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

How to manage non-static function for an Action<>?

Discussion in 'Scripting' started by qqqqqqqqqqqqqqqqq1, Jun 20, 2020.

  1. qqqqqqqqqqqqqqqqq1

    qqqqqqqqqqqqqqqqq1

    Joined:
    Jun 3, 2020
    Posts:
    13
    Code (CSharp):
    1.  
    2. public class ClassOne {
    3.    public TargetClass<string, dynamic> item = new TargetClass<string, dynamic>(new Action<string, dynamic>(itsme));
    4.    // ^^^ Cannot access non-static method 'itsme' in static context
    5.    // This doesn't work, because target method (itsme) needs to be static, but I can't have it static, it has to be THIS version in THIS instance
    6.  
    7.  
    8.    void Update()
    9.    {
    10.       if (Input.GetKeyDown(KeyCode.A)) { item.InvokeInside(123); }
    11.    }
    12.  
    13.    public void itsme(dynamic one, dynamic two)
    14.    {
    15.       Debug.Log($"received: {one} and number {two}");    // should say: received: "yep" and number 123
    16.    }
    17.  
    18. }
    19.  
    20.  
    21. public class TargetClass<T, T1>
    22. {
    23.    Action<T, T1> deleg;
    24.    public TargetClass(Action<T, T1> internalDeleg) => deleg = internalDeleg;
    25.    public void InvokeInside(int counting) => deleg("yep", counting);
    26.    // ^^^ Argument type 'string' is not assignable to parameter type 'T'
    27. }
    28.  
    There are two errors I added in comments in the code above. And my target is to have
    itsme
    and
    item.InvokeInside(123)
    execute and not fail.
     
    Last edited: Jun 20, 2020
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,385
    When declaring class members and initializing them, you can't access other class members unless they're static. If you need to access other class members, do so in the constructor or other method. Like so:
    Code (csharp):
    1.  
    2. public TargetClass<string, dynamic> item;
    3.  
    4. void Awake()
    5. {
    6.     item = new TargetClass<string, dynamic>(new Action<string, dynamic>(itsme));
    7. }
    8.  
    In the context of this line the generic class TargetClass<T, T1> does not know what type T or T1 is. As a result you can't treat it as any specific type.

    So when you say:
    Code (csharp):
    1. deleg("yep", counting)
    You're assuming that 'deleg' takes in a string for T and an int for T1.

    Sure, you've instantiated an instance of TargetClass<string, dynamic> that would accept these. But that's outside of this context. That's technically a child class of TargetClass<T,T1>.

    There's no easy work around for this... because it just doesn't make sense.

    Is there a reason your TargetClass is generic yet in its implementation you make assumptions about what T/T1 are?

    As for coming up with workarounds, there are many that exist. But they all depend on what your actual intents are. And since I don't know what your actual intents are since all the code appears to just be pseudo code for demonstration purposes... well, I could narrow it down to a specific work around that fits your needs.
     
    qqqqqqqqqqqqqqqqq1 likes this.
  3. qqqqqqqqqqqqqqqqq1

    qqqqqqqqqqqqqqqqq1

    Joined:
    Jun 3, 2020
    Posts:
    13
    Information you provided is just enough for me to solve this, but this leaves me with one more question.
    One of the T in TargetClass is int/string/float (depends for each instance), and the receiving function (itsme) has type dynamic in its parameters. That doesn't work due to type mismatch (I actually don't know why, thought dynamic was a catch-all). Is there a way to work this around?