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. Dismiss Notice

How to pass a generic value to a function

Discussion in 'Scripting' started by studiostartunity, Jun 5, 2019.

  1. studiostartunity

    studiostartunity

    Joined:
    May 3, 2019
    Posts:
    24
    Hello,
    the question is simple but tricky.

    I'm trying to write a function able to store a value in a dictionary. The fact is that I don't want to specify the type of this value. Basically, I want allow the user to pass any kind of value to this function, for example a "classic" value (integer, float, boolean, string, etc.) or a Unity type (GameObject, AudioSource, Particle, etc.). The dictionary should be able to store this value.

    For example, a function like this:
    Code (CSharp):
    1.  
    2. void MyFunction (valueToStore, string id) {
    3.  
    4.   MyDictionary.add(id, valueToStore);
    5.  
    6. }
    7.  
    Then, the user will convert this "generic" value to the proper type by casting it.

    I was thinking to use object type, but I don't know if it might expose some problem.

    Is there a proper way to do this in Unity C#?
    Thanx.
     
  2. TheRealRan

    TheRealRan

    Joined:
    Jun 3, 2019
    Posts:
    18
    I might be wrong, but I believe something like this would work:

    Code (CSharp):
    1. void MyFunction<T>(T valueToStore, string id)
    2. {
    3.     MyDictionary.add(id, valueToStore);
    4. }
    This way you would be able to call the method like this:

    Code (CSharp):
    1. MyFunction<int>(10,"id");
    I am not sure how MyDictionary would be declared, but one of these options might work:

    Code (CSharp):
    1. Dictionary MyDictionary<String, GameObject>;
    2. Dictionary MyDictionary<String, Object>;
    3. Dictionary MyDictionary<String, <T>>; // I don't think this one will work
    4. Dictionary MyDictionary<String, dynamic>; // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/dynamic
    I've never done this, so I apologize if it does not work.
     
  3. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,745
    This won't of course, this will go:

    Code (CSharp):
    1. public class SomeClass<T> {
    2. private Dictionary<string, T> MyGenericDictionary;
    3. }
    Note the T type parameter on the class, you don't need it on MyFunction anymore.
     
  4. studiostartunity

    studiostartunity

    Joined:
    May 3, 2019
    Posts:
    24
  5. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    In cases like this I have used a Dictionary<string, object> as you have suggested. This works fairly well, if you write a set of accessor functions (e.g. storeInt(string key, int value)) you can even implement implicit conversions if the type that was found didn't match the type expected.
    Make sure to re-visit this highly illuminating article on boxing/unboxing, and you should be good to go in a few minutes :)
     
    GoliathAT likes this.
  6. studiostartunity

    studiostartunity

    Joined:
    May 3, 2019
    Posts:
    24
    Thank you for all suggestions. I tested the use of object with the most important Unity and native types and it supports all of them. Thanx.
     
  7. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    Just don't overpraise it. It allocates and produces lots of garbage when you're boxing value type to objects.
    As it allocates references on the heap.

    I'd say you should avoid doing value type -> object conversions when writing game applications.