Search Unity

Getting the Generic T type of a class as a String

Discussion in 'Scripting' started by NeatWolf, Dec 2, 2016.

  1. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    924
    Hi,

    I have this base script, which should handle generic attributes changes when the Age within the game changes ( a game with a time switching mechanic)

    I know I shouldn't be able to Serialize the fields that it contains - I should be able to serialize them in the subclasses.

    BUT

    What I don't know is how to return the T.ToString() value out of T just for debugging purposes. (Look at the Debug.LogWarning line: I don't know how to complete it)

    T should be a simple value type like string, bool, int, float, etc. (possibly also something more complex but I don't need it for now)

    Could you please help me? Shoud I declare T as a specific class? Which one?

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using AdvancedInspector;
    4.  
    5. public class AgeSpecificAttribute<T> : MonoBehaviour {
    6.     public T valuePresent;
    7.     public T valueAlternate;
    8.  
    9.     [ReadOnly]
    10.     public T value;
    11.  
    12.     protected virtual IEnumerator Start()
    13.     {
    14.         // 1 frame later
    15.         yield return null;
    16.      
    17.         SetAgeAppropriateAttribute();
    18.     }
    19.  
    20.     public virtual T SetAgeAppropriateAttribute(Ages age)
    21.     {
    22.         if (AgeManager.IsPresent(age))
    23.             value = valuePresent;
    24.         else
    25.             value = valueAlternate;
    26.      
    27.         //Rest is defined in subclasses
    28.         if (!ApplyAgeAttribute())
    29.         {
    30.             Debug.LogWarning("Impossible to set " + GetType().ToString() + " to " + T)
    31.         }
    32.      
    33.         return value;
    34.     }
    35.  
    36.     public virtual T SetAgeAppropriateAttribute()
    37.     {
    38.         return SetAgeAppropriateAttribute(AgeManager.Age);
    39.     }
    40.  
    41.     public virtual bool ApplyAgeAttribute(T ageValue)
    42.     {
    43.         // Implemented in subclasses
    44.     }
    45. }
    46.  
     
  2. Dameon_

    Dameon_

    Joined:
    Apr 11, 2014
    Posts:
    542
    Debug.Log(typeof(T).ToString());
     
    wesleywh and NeatWolf like this.
  3. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    924
    Thanks, but it didn't work:
    "Assets/z_Scripts/AgeSpecificAttributes/AgeSpecificAttribute.cs(30,97): error CS0119: Expression denotes a `type parameter', where a `variable', `value' or `type' was expected"

    I actually needed just "value.ToString()" (value is of T type) and it's working fine.

    I'm still curious about how to actually get the type of T in string. The autocompletion of ScriptInspector 3 isn't offering me any useful methods.
     
  4. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    924
    Would it be possible to define T as Nullable?
     
  5. Dameon_

    Dameon_

    Joined:
    Apr 11, 2014
    Posts:
    542
    Sorry, you saw my post just before the edit. See the slightly modified answer.
    To constrain T to nullable types, you do "where T : class" after what you want constrained, the class definition or method definition.
     
    jesseparsons1 and NeatWolf like this.
  6. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    924
    Thanks! That should definitely work :)

    I still haven't tried but... since I mostly need T to be a value type (int, string, enum, bool, etc.), would defining T as a class still allow me to use such types?
    I mean, I should be able to get a bool that can also be null. I'm not sure which language I remember this "Nullable" type to be from. Maybe Java? I can't remember. Probably it's not in Unity C# tho.
     
  7. Dameon_

    Dameon_

    Joined:
    Apr 11, 2014
    Posts:
    542
    C# primitives are not nullable types. A string is nullable, but think of that more like an array of characters.
     
  8. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    If you put a restriction on T to be a reference type, you will not be able to use this generic class with value types.

    C# has a type Nullable<T> which allows value types to take a null value. By default a bool cannot be null but a Nullable<bool> can. C# provides a shorthand for this framework feature, so Nullable<bool> can be written as bool?

    Making generics work with Nullable<T> is a bit weird since Nullable<T> is itself a value type. If you can provide more information about what you are trying to do we might have other ideas.