Return Type From Function

Is there any way to return parameter type instead of a parameter value from a function?

List<DetermineCorrectType(0)> myTypeList = new List<DetermineCorrectType(0)>;

public Type DetermineCorrectType(givenVersion) {
    if (givenVersion == 0) {
        return saveVersion1;
    } else if (givenVersion == 8) {
        return saveVersion2;
    } else {
        return saveVersion4;
    }
}

I have a bunch of serializable classes that is use for backwards compatibility with previous saves (when the user updates version). I was hoping to write a function that would return the correct class for the given version.

To get type of variable you can use GetType().

object obj = "66";

if(obj.getType() == typeof(int)){

   //...
}

or you can return it as object but Im not sure if it is good way of doing it:

public object GetTypes()
        {

            object c = 5;
          

            if (c.GetType() == typeof(int))
            {
                return c;

            }

            return 0;
        }

so, to use my example, you’d implement it like

    List<DetermineCorrectType(0).GetType> myTypeList = new List<DetermineCorrectType(0).GetType>;
    public Object DetermineCorrectType(int givenVersion) {
        if (givenVersion == 0) {
            return new saveVersion1();
        } else if (givenVersion == 8) {
            return new saveVersion2();
        } else {
            return new saveVersion4();
        }
    }

but that returns the error “cannot implicitly convert type ‘saveVersion1’ to ‘UnityEngine.Object’”

It’s confusing UnityEngine.Object and the .NET’s object, If you’re not using Monobehavior (GameObject script) then just exclude ‘using unityEngine’ stuff from the top of your code.

Otherwise, refer to it as ‘System.Object’ instead of just Object. I corrected it using System.Object in the quotes.

2 Likes

That works great, up until the bit where I try to create a list of that type. I get “Using the generic type ‘List’ requires 1 type arguments”. I am really lost here.

List<DetermineCorrectType(0).GetType()> myTypeList = new List<DetermineCorrectType(0).GetType()>();
    public Object DetermineCorrectType(int givenVersion) {
        if (givenVersion == 0) {
            return new saveVersion1();
        } else if (givenVersion == 8) {
            return new saveVersion2();
        } else {
            return new saveVersion4();
        }
    }

You can’t do it in this way, since you need to declare the Type at compile time. To get around it you can do this:

var listType = typeof(List<>).MakeGenericType(DetermineCorrectType(0).GetType());
var listInstance = Activator.CreateInstance(listType);

Also, note that you can have a function return Type, which is the resulting type of GetType() function.

public Type GetObjectType(Object obj)
    {
        return obj.GetType();
    }

What would the C# equivalent of this be?

That is C#

I realize now that I need to deserialize into that list. But it rejects this method.

//In this instance listType returns 'saveVersion.saveVersion2' type, or rather the monobehavior 'saveVersion+saveVersion2'
var listType = typeof(List<>).MakeGenericType(DetermineCorrectType(0).GetType());
CSharp]savedGames = (List<listType>)bf.Deserialize(file);
//Returns "Cannot implicitly convert type 'System.Collections.Generic.List<listType>' to 'System.Collectoins.Generic.List<saveVersion.saveVersion2>'
//I have tried various ways of using the 'System.Activator' line in this, but I frankly don't understand it enough to put an example up that is remotely close to what might work

Is there any way to get a function to return a type where I can deserialize a file into a list of that type? (final addition, I promise!)

listType should already be a List. So you are not making a proper cast. I don’t have an IDE in front of me right now, but you should be able to do:

CSharpSavedGames = bf.Deserialize(file) as listType.GetType()

or something similar.

It really doesn’t like that. :eyes: If you could update when you get a chance to look over the IDE that’d be awesome, thanks!

Yeah, You can’t actually do this. What you are trying to do, is essentially cast an object to a different type at runtime, while actually a cast operation happens at compile time. Judging by the response from your compiler, it should be something like :

List<saveVersion.saveVersion2> CSharpSavedGames = bf.Deserialize(file);

The question is where do you define CSharpSavedGames, since this is what you are trying to cast to. Also, what is Serialize() returning?

I went down this path with a serializer I was writing and ran into these problems you are facing in the past. It never actually worked out properly, and just created more issues. I would suggest that you re-consider your approach.

Your post helped me figure it out. What I can do, and this works so far, is:

var listType = typeof(List<>).MakeGenericType(DetermineCorrectType(0).GetType());
var listInstance = Activator.CreateInstance(listType);
listInstance  = bf.Deserialize(file);

Thanks for all your help!