I've created a class that inherits from List to be used on my Unity-firebase project porpouses.
using System.Collections.Generic;
public class FirestoreList<FirestoreData, PlainData> : List<FirestoreData>, IConvertToPlainData<List<PlainData>>
where FirestoreData : IConvertToPlainData<PlainData>
where PlainData : IConvertToFirestore<FirestoreData>
{
public FirestoreList() : base() { }
public FirestoreList(List<PlainData> plainDataList) <-- this is the 8th line
{
this.Clear();
foreach (PlainData plainData in plainDataList)
{
this.Add(plainData.ToFirestoreData());
}
}
public List<PlainData> ToPlainData()
{
List<PlainData> convertedPlainDataList = new List<PlainData>();
if (this.Count > 0)
{
foreach (FirestoreData firestoreData in this)
{
convertedPlainDataList.Add(firestoreData.ToPlainData());
}
}
return convertedPlainDataList;
}
}
The interfaces are the following ones (basically functioning as a Serialize/Deserialize):
public interface IConvertToPlainData<T>
{
T ToPlainData();
}
public interface IConvertToFirestore<T>
{
T ToFirestoreData();
}
This code works on the Editor, on runtime etc, but when I try to build using IL2CPP (cause I'm targeting mobile stores) the following error on the build appears:
IL2CPP error for method 'System.Void FirestoreList`2::.ctor(System.Collections.Generic.List`1<PlainData>)' in FirestoreList.cs:8
Additional information: Unable to retrieve the runtime generic context for 'System.Collections.Generic.List`1<PlainData>'.
I don't understand the error message, and I didn't find any similar references on google, all that I have is this link about Unity and IL2CPP ScriptingRestrictions :(
Can someone help me or at least point me to the answer? Thanks!
EDIT: An example of the classes that I use to show the generic parameter that I use to instantiate FirestoreList:
[Serializable]
public class User : IConvertToFirestore<User_FirestoreData>
{
[SerializeField] public List<User> usersList = new List<User>();
public User_FirestoreData ToFirestoreData()
{
User_FirestoreData userFire = new User_FirestoreData()
{
usersList = new FirestoreList<User_FirestoreData, User>(this.usersList)
};
return userFire;
}
}
[FirestoreData]
public class User_FirestoreData : IConvertToPlainData<User>
{
[FirestoreProperty] public FirestoreList<User_FirestoreData, User> usersList { get; set; }
public User ToPlainData()
{
User user = new User()
{
usersList = this.usersList.ToPlainData(),
};
return user;
}
}
EDIT2:
My thoughs are that when I'm using this.usersList.ToPlainData()
there's no specification of what is FirestoreData
and PlainData
, so the compiler can't know what cast to do (or something similar).
For the moment the only solution have been to remove the FirestoreList class and implement a couple of extension methods for List like these ones:
public static List<PlainData> ToPlainData<PlainData, FirestoreData>(this List<FirestoreData> list) where FirestoreData : IConvertToPlainData<PlainData> where PlainData : IConvertToFirestore<FirestoreData>
{
List<PlainData> convertedPlainDataList = new List<PlainData>();
if (list.Count > 0)
{
foreach (FirestoreData firestoreData in list)
{
convertedPlainDataList.Add(firestoreData.ToPlainData());
}
}
return convertedPlainDataList;
}
public static List<FirestoreData> ToFirestoreData<FirestoreData, PlainData>(this List<PlainData> list) where FirestoreData : IConvertToPlainData<PlainData> where PlainData : IConvertToFirestore<FirestoreData>
{
List<FirestoreData> convertedFirestoreDataList = new List<FirestoreData>();
if (list.Count > 0)
{
foreach (PlainData plainData in list)
{
convertedFirestoreDataList.Add(plainData.ToFirestoreData());
}
}
return convertedFirestoreDataList;
}
As you are forced to call it like this: this.charactersList.ToPlainData<User, User_FirestoreData>()
seems like there is no problem with the JIT or AOT.