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

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:
    971
    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.