-2

I have a superclass, MySuperclass, and a 2 subclasses of MySuperclass; MySubclass1 and MySubclass2. I want to be able to call an instance method that relies on the type of the subclass.

For example, I want to be able to call MySubclass.Serialize() on any instance of a subclass of MySuperclass and have it call Json.SerializeToBytes<T>(T toSerialize) on that object, replacing T as appropriate.

public class MySuperclass 
{
    // of course, this does not work.
    public byte[] SerializeToBytes() 
        => Json.SerializeToBytes<typeof(this)>(this); 
}

public class MySubclass1 : MySuperclass
{
    ...
}

public class MySubclass2 : MySuperclass
{
    ...
}

Then I could do:

byte[] bytes; 
var mySubclass1Object = new MySubClass1();

bytes = mySubclass1Object.SerializeToBytes();

// the above is equivalent to (though the type parameter would normally be implied)
bytes = Json.SerializeToBytes<MySubclass1>(mySubclass1Object);

How can I achieve this?


As per a comment's request, the library I am using is the Utf8Json library. The Json.SerializeToBytes<T>(T toSerialize) is defined as: **

public static byte[] SerializeToBytes<T>(T obj)
{
    return JsonSerializer.Serialize<T>(obj);
}

Footnotes

* I have found this post. But it does not answer my question. In this case, they can refer to the subclass just using the type of the superclass, but here the serializer needs access to the subclass and all its extra methods and attributes to properly serialize it. They are also not passing the type as a type parameter to some method, which I need to do.

** I was hoping for this to be something that could be used in other situations too, where I can access the type of a subclass from a method defined in the superclass.

I don't want to use override, as it would require me to rewrite the .Serialize() method for each subclass

halfer
  • 19,824
  • 17
  • 99
  • 186
doliphin
  • 752
  • 6
  • 22
  • Does this answer your question? [Practical usage of virtual functions in c#](https://stackoverflow.com/questions/1062102/practical-usage-of-virtual-functions-in-c-sharp) – Charlieface Feb 21 '21 at 17:06
  • Incidentally `Json.SerializeToBytes` uses reflection so it can see the actual object type that has been passed in – Charlieface Feb 21 '21 at 17:07
  • @Charlieface Would the solution in the question you have linked not require me to create a new method for each subclass, overriding the superclass's method? I'm doing this to save myself from writing a `.Serialize()` for like 20 classes. – doliphin Feb 21 '21 at 17:11
  • Then the answer is my second comment. You can make one base function, without any override, and `Serialize` should work it out. **Which serializer/library are you using?** – Charlieface Feb 21 '21 at 17:13
  • @Charlieface Implementing something like `public byte[] SerializeToBytes() => Json.SerializeToBytes(this);` does not work successfully for any of the subclasses – doliphin Feb 21 '21 at 17:14
  • @Charlieface I have added that information to the body of the post, however I was hoping for this to be something that could be used in other situations too, where I can access the type of a subclass from a method defined in the superclass – doliphin Feb 21 '21 at 17:18
  • What is your question? Evething seems ok as it is. You dont need any override already. – Serge Feb 21 '21 at 17:22
  • 1
    You may find [this](https://ericlippert.com/2011/02/02/curiouser-and-curiouser/) interesting. You want to genricize the base class as `MySuperclass where T : MySuperclass` which looks crazy, but works. Then you can declare `string Serialize` in the base class – Charlieface Feb 21 '21 at 17:23
  • 1
    You could also just pass `this.GetType()` and use the non-generic overload of `Serialize`. No need to use any recursive generics, particularly since you only want it for one purpose. In other words your SerializeToBytes method could be nongeneric as well. `JsonSerializer.Serialize(obj, obj.GetType())` – pinkfloydx33 Feb 21 '21 at 17:54
  • Use the non generic version `public static byte[] SerializeToBytes(object obj) { return JsonSerializer.NonGeneric.Serialize(obj); }` – Jesús López Feb 21 '21 at 18:01
  • @JesúsLópez As I said in my post, this is not a question about serialization, but about OOP. I want to be able to use this more generally, and this was just an example. I have found a solution that works, it is below. – doliphin Feb 21 '21 at 18:07
  • I would appreciate it if someone could let me know why they do not think this question is focused, and so much so, that it couldn't just have been tweaked a little? – doliphin Feb 21 '21 at 18:10

1 Answers1

1

Thanks to @Charlieface for the link to the explanation of this.

This implementation works, you need to cast to T.

public class MySuperclass<T> where T : MySuperclass<T>
{
    public byte[] SerializeToBytes() 
        => Json.SerializeToBytes((T)this); 
}

public class MySubclass1 : MySuperclass<MySubclass1>
{
    ...
}
doliphin
  • 752
  • 6
  • 22