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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Passing a System.Type into < > without explicitly defining Type?

Discussion in 'Scripting' started by hoperin, Jul 19, 2018.

  1. hoperin

    hoperin

    Joined:
    Feb 9, 2014
    Posts:
    52
    I'm trying to figure out how to tell CreateTrack<System.Type>() what kind of track type to crate without explicitly typing in the type, because I have maaany track types. This is for a duplication code, where I am going through a bunch of tracks of different types and creating duplicates of them, each of the correct type, of course.

    I've tried passing System.Type ttype, as well as the string version typeString, but it seems it really wants me to type out the actual Type. I could make a switch case that contains every single type and a CreateTrack<System.Type>() line in each of them, but that seems really unideal, and I'd need to update the hardcode every time I added a track type.

    Code (CSharp):
    1.  void CheckForTrack(System.Type ttype)
    2.     {
    3.         string typeString = ttype.ToString();
    4.  
    5.         targetTrack = null;
    6.         foreach (TrackAsset track in newTL.GetOutputTracks())
    7.         {
    8.             if (track.GetType() == ttype) {
    9.                 targetTrack = track;
    10.                 break;
    11.             }
    12.         }
    13.  
    14.         //if one hasnt been found create new track
    15.         if (targetTrack == null) {
    16.            targetTrack = newTL.CreateTrack<?????>(null, typeString);
    17.         }
    18.     }
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    You can't. It's required to be known for compile time type-safety. You can pass it as a parameter and cast your result though.
     
    Kiwasi and hoperin like this.
  3. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Can you give an example of two or more different tracks? Do you want to model those as different types? If so, you could have an interface or a base class, and constraint the generic type parameter to that common type and with the new() constraint.

    Though I'm not sure whether this makes actually sense, I doubt I would approach the definition of different tracks in such a way.
     
    Last edited: Jul 19, 2018
    hoperin likes this.
  4. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    Defining base class and setting it as a constraint is a best solution in this case.
    This will also allow you to avoid using reflection at all, and a result - it's costs.
     
    hoperin likes this.
  5. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    I would approach it the other way around. I would have the main method that does the work take a Type object as an argument, and then if you want, you can also easily provide a generic method. So something like:

    Code (CSharp):
    1. public TrackAsset CreateTrack(Type trackType)
    2. {
    3.    // ...does some work, returns a new TrackAsset instance.
    4. }
    5.  
    6. public TrackAsset CreateTrack<T>()
    7. {
    8.    return CreateTrack(typeof(T));
    9. }
    Sam
     
  6. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    The answer is reflection. You can pass in a System.Type as a regular argument, then you can use Activator.CreateInstance to create the actual instance.

    Fair warning: If the answer is reflection, the question is normally wrong.
     
    xVergilx likes this.
  7. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    That wouldn't work well with MonoBehaviours (or UnityEngine.Objects in general), though, even if it wasn't the a bad choice.
     
    Kiwasi likes this.
  8. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,383
    You have to pass something more specific than System.Type. If you already know you're dealing with Tracks, then pass some kind of Track Type.

    You don't want to use reflection here, as pointed out already, but instead you want write code that is more explicit and deliberate.
     
    Suddoha likes this.