C
C#2mo ago
Nanior

Calling static method of interface via it's type

There's an interface called ISerializer. ISerializer implements two static methods called Serialize and Deserialize. There's a class that implements ISerializer called ArraySerializer. ArraySerializer is requires an generic type parameter of type ISerializer... The ArraySerializer needs to call the Serialize/Deserialize method of the generic type parameter
34 Replies
Nanior
NaniorOP2mo ago
What bugs me is that I know that the Type implements ISerializable, why can't I use the static methods of it?
c#
public class ArraySerializer<T, TSerializer> : ISerializer<T[]> where TSerializer : ISerializer<T>
{
public static void Deserialize(Stream stream, out T[] value)
{
value = new T[BitConverter.ToInt32(stream.Read(sizeof(int)))];
for (int i = 0; i < value.Length; i++)
{
value[i] = TSerializer.Deserialize()
}
}

public static void Serialize(Stream stream, T[] value)
{
stream.Write(BitConverter.GetBytes(value.Length));
}
}
c#
public class ArraySerializer<T, TSerializer> : ISerializer<T[]> where TSerializer : ISerializer<T>
{
public static void Deserialize(Stream stream, out T[] value)
{
value = new T[BitConverter.ToInt32(stream.Read(sizeof(int)))];
for (int i = 0; i < value.Length; i++)
{
value[i] = TSerializer.Deserialize()
}
}

public static void Serialize(Stream stream, T[] value)
{
stream.Write(BitConverter.GetBytes(value.Length));
}
}
sibber
sibber2mo ago
what type implements ISerializable?
blueberriesiftheywerecats
Where T : ISerializer<T> Or if your type itself can't be a serializer, then just create an instance of TSerializer
sibber
sibber2mo ago
this is all static here which yeah isnt a very good idea but whatever what do you expect TSerializer.Deserialize() to do?
Nanior
NaniorOP2mo ago
Deserialize is a method that reads from a stream and returns something of Type T, that's what ISerializer is meant for (ISerializer is custom, not to be mistaken with whatever other interface that might be named the same) Unfortunately turns out it doesn't quite work the way I intended, particularly the part about static methods not being reference-able via the type Might have to completely rethink how this is supposed to work...
sibber
sibber2mo ago
yeah but youre not giving it any arguments
Nanior
NaniorOP2mo ago
I'm not giving it any arguments because look like it does not exist... Basically apparently you can't normally call a static method by the type That's why I'm asking, because I might need to step back and comepletely rethink the whole system, cus looks like my original plan is invalid in multiple ways How would you write something like this? It's meant to be used for saving primarily, converting binary from and to other types
sibber
sibber2mo ago
im not sure what youre asking
MODiX
MODiX2mo ago
sibber
REPL Result: Success
Print<Test>();

void Print<T>() where T : ITest
{
Console.WriteLine(T.Get());
}

interface ITest
{
static abstract int Get();
}

class Test : ITest
{
public static int Get() => 5;
}
Print<Test>();

void Print<T>() where T : ITest
{
Console.WriteLine(T.Get());
}

interface ITest
{
static abstract int Get();
}

class Test : ITest
{
public static int Get() => 5;
}
Console Output
5
5
Compile: 420.469ms | Execution: 74.448ms | React with ❌ to remove this embed.
sibber
sibber2mo ago
thats valid
MODiX
MODiX2mo ago
sibber
REPL Result: Success
return ArraySerializer<int, IntSerializer>.Deserialize();

interface ISerializer<T>
{
static abstract T Deserialize();
}

class IntSerializer : ISerializer<int>
{
public static int Deserialize() => 5;
}

class ArraySerializer<T, TSerializer> : ISerializer<T[]>
where TSerializer : ISerializer<T>
{
public static T[] Deserialize()
{
var arr = new T[3];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = TSerializer.Deserialize();
}

return arr;
}
}
return ArraySerializer<int, IntSerializer>.Deserialize();

interface ISerializer<T>
{
static abstract T Deserialize();
}

class IntSerializer : ISerializer<int>
{
public static int Deserialize() => 5;
}

class ArraySerializer<T, TSerializer> : ISerializer<T[]>
where TSerializer : ISerializer<T>
{
public static T[] Deserialize()
{
var arr = new T[3];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = TSerializer.Deserialize();
}

return arr;
}
}
Result: int[]
[
5,
5,
5
]
[
5,
5,
5
]
Compile: 428.780ms | Execution: 43.170ms | React with ❌ to remove this embed.
sibber
sibber2mo ago
i think youre trying to do something like this? what isnt working for you?
Nanior
NaniorOP2mo ago
Huh... Idk why it's working for you... Sure didn't when I did it? Is it Unity's C# version or something?
sibber
sibber2mo ago
oh unity yeah it uses an old version, thats not supported
Nanior
NaniorOP2mo ago
Back in mine, static interface methods must have a body, yours doesn't
sibber
sibber2mo ago
did unity upgrdae to a newer version or something? static interface methods are fairly new iirc anyway you need to declare them abstract in the interface btw there are many serialization libraries so theres no need to do this for something other than learning
Nanior
NaniorOP2mo ago
MessagePack always breaks badly, somehow I originally struggled with MessagePack a lot to get it to work in the first place
sibber
sibber2mo ago
breaks how trying to fix it would be easier than writing your own
Nanior
NaniorOP2mo ago
Later I struggled with it for days again when trying IL2CPP for potentially faster runtime And now it's when I tried migrating to Unity6
sibber
sibber2mo ago
theres also MemoryPack which doesnt do encoding
Nanior
NaniorOP2mo ago
Typically resolver issues, something about revolver not defined in standard resolver, or entirely not found And turned out later that I'd need to use .NET framework instead, because for some reason it didn't wanna work normally when on .NET standard I can't access the project right now so I can't tell what exactly the issue is anymore Um... Idk that package, can try I guess MessagePack is said to be very fast and compact, that's why I used it, but maybe it's not a robust design or something, idk, it just frequently ends up in trouble, mostly issues with custom type resolvers
sibber
sibber2mo ago
ive never used it before personally, but its very popular and seems fairly battle tested so it must be robust it does look somewhat tricky to use in some cases tho tradeoff for performance MemoryPack is made by the same person
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
Nanior
NaniorOP2mo ago
O.o Well, I had another look at MessagePack's documentation, and I see something I can try next time I work on my project... Might be that for some reason Unity6 doesn't automatically register the generated resolver like when I was trying IL2CPP, so I'll need to include the registry function At least, it sounds like it makes sense When my brother was trying to fix it he insisted that the only solution is to use .NET framework instead, which is why I decided to avoid MessagePack and try write my own
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
sibber
sibber2mo ago
but for a game save file how would this happen
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
sibber
sibber2mo ago
thats not really a volunrability you can say that about any format
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
sibber
sibber2mo ago
it seems to just dump the raw bytes no encoding so the goal is performance if i understood correctly at least
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
sibber
sibber2mo ago
oh i dont think they meant cross lang
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
sibber
sibber2mo ago
anyway yeah protobuf seems nice for that
Want results from more Discord servers?
Add your server