Serialize a Static Class

Serialize a Static Class?

There are never any instances of static classes: they are both abstract and sealed in the IL, so the CLR will prevent any instances being created. Therefore there is nothing to serialize. Static fields are never serialized, and that's the only sort of state that a static class can have.

Your question about XML serialization makes no sense, as no-one can ever have created an instance of the static class to start with.

How do i serialize static class?

You normally serialize instances. You can't have an instance of a static class, so it makes no sense to serialize it.

If you need to serialize the static state of a static class, then you should probably make it non-static to start with. If you really need to keep the static class static but serialize the static state, you could create a normal class with the same variables (but instance variables instead of static ones), and make methods in your static class to create an instance from the current static state, or replace the current static state based on an instance passed in. But fundamentally it's not terribly pleasant to do so...

Making static class data serializable

First of all: Your issue has nothing to do with a field being serializable or not.

It is rather related to your instanced class field i not being accessible from a static context. As the error states you would need an instance of your class in order to access it there but

As also mentioned classes of type MonoBehaviour are not allowed to have any constructor and may not be instanciated via the new keyword in Unity. The only allowed ways of creating instances of components is via Instantiate, AddComponent or via the constructor of e.g. new GameObject("someName", typeof(YOUR_COMPONENT));.


You don't need a Singleton for what you want. It sounds like you actually would want to go this way round:

public class myClass : MonoBehaviour
{
// This one you set via the Inspector
[SerializeField] private int _i;

// This is now a read-only property
// That can only be set by this class
public static int i { get; private set; }

private void Awake()
{
// Your instance can always access its static fields
// So this way you can assign the value
i = _i;
}
}

In general we would need more input in order to figure out your actual usecase here. It is also possible that you could rather use an entirely static class like e.g.

public static class myClass
{
public static int i = 42;
}

this makes your field not serialized but simply accessible from everywhere without the need of an instance in the Scene. You would simply access it from another MonoBehaviour like e.g.

public class Example : MonoBehaviour
{
private void Start()
{
Debug.Log(myClass.i);
}
}

Or you might want to make your class not static at all but rather access it through the correct reference like

[Serializable]
public class myClass
{
public int i = 42;
}

public class Example : MonoBehaviour
{
// Since it is tagged Serializable and now serialized in the Inspector
// an instance is created for this field automatically
[SerializedField] private myclass _myClass;

private void Awake()
{
Debug.Log(_myclass.i);
}
}

How to serialize static data members of a Java class?

The first question is why you need to serialize the static members?

Static members are associated with the class, not the instances, so it does not make sense to include them when serializing an instance.

The first solution is to make those members not static. Or, if those members are the same in the original class and the target class (same class, but possibly different runtime environments), don't serialize them at all.

I have a few thoughts on how one could send across static members, but I first need to see the use case, as in all cases that means updating the target class, and I haven't found a good reason to do so.

Serializable Static class variables in Python

Quoting the section on "What can be pickled and unpickled?"

Similarly, classes are pickled by named reference, so the same restrictions in the unpickling environment apply. Note that none of the class’s code or data is pickled, so in the following example the class attribute attr is not restored in the unpickling environment:

class Foo:
attr = 'a class attr'

picklestring = pickle.dumps(Foo)

So because attr, or in your case count, is part of the class definition, it never gets pickled. In your 'write' example, you're printing Sample.count which does exist but is not pickled in the first place.

You could store Sample.count in each instance as _count and put Sample.count = self._count. But remember that since your d is a dict, they may unpickle in any order. So essentially this won't work.

You'll need to add __setstate__ to your class customize the way it pickles and put in some flag value (like _count) which you then manipulate (via whatever logic works consistently) in __getstate__. (Edit: doesn't help with the given problem unless you store count in a global variable and access that in getstate and manipulate further each time an object is unpickled.)

Another potential workaround but yuck: Add a variable to your dict d so that it also gets pickled. When you read it back, restore with Sample.count = d['_count']. So before pickle.dump(d,f) when you pickle, do d['_count'] = Sample.count.

Important caveat: This is not actually allowing you to pickle Sample.count since what you're actually pickling (d) is a dictionary of Samples.

Edit: The Sample.count = len(d.values()) which you've put as a workaround is very specific to your use case and not to class attr's in general.

Serialization of static inner class

A static inner class is no different than a top-level class in this respect: it can be serialized if it is declared to implement Serializable (or is a subclass of a class declared to implement Serializable). Also, as with top-level classes, all objects encountered during serialization at run time must be serializable to avoid a NotSerializableException. Since the inner class is static, the nature of the outer class is irrelevant to this.

Java static serialization rules?

statics are implicitly transient, so you don't need to declare them as such.

Serialization is for serializing instances, not classes. static fields (methods are irrelevant since they are part of the class definition so they aren't serialized) will be reinitialized to whatever value they are set to when the class is loaded.

If you have a mutable static field, then the changes made to that value will be lost.

PHP - serialize a class with static properties

As I mentioned in the comment, this is more a software design question than a question how to achieve this with PHP.

A static property is not part of the state of an object and will therefore not being serialized with it.

I'll give you a short example how I would solve a related problem. Imagine you have the following message class, that has a static $id property to make sure all instances have a unique id:

class Message {

public static $id;

public $instanceId;

public $text;

/**
*
*/
public function __construct($text) {
// the id will incremented in a static var
if(!self::$id) {
self::$id = 1;
} else {
self::$id++;
}

// make a copy at current state
$this->instanceId = self::$id;
$this->text = $text;
}
}

Serialization / Unserialization code:

$m1 = new Message('foo');
printf('created message id: %s text: %s%s',
$m1->instanceId, $m1->text, PHP_EOL);
$m2 = new Message('bar');
printf('created message id: %s text: %s%s',
$m2->instanceId, $m2->text, PHP_EOL);

$messages = array($m1, $m2);

$ser1 = serialize($m1);
$ser2 = serialize($m2);

$m1 = unserialize($ser1);
printf('unserialized message id: %s text: %s%s',
$m1->instanceId, $m1->text, PHP_EOL);
$m2 = unserialize($ser2);
printf('unserialized message id: %s text: %s%s',
$m2->instanceId, $m2->text, PHP_EOL);

To make sure that the id is unique across multiple script runs further work is nessary. You'll have to make sure that Message::$id is initialized before any object creation, using the value from last script run. This will get additionally wired when it comes to parallel PHP request on a webserver.


Its just an example with the simplest static property I know: an instance counter. In this case I would do so. But I hope you see that there is further work required to serialize / unserialize static properties without have side effects. And this depends on your application needs.

This question cannot be answered general I tend to say it makes no sense in any case to serialize static members. But I would appreciate comments on this.

How to serialize static or const member variables using JSON.NET?

It could certainly serialize the static variable if it wanted to. Serialization is done by inspecting objects and types with the Reflection APIs, and those APIs allow you to do "anything" -- there is no technical reason these values cannot be serialized.

There is, however, a logical reason not to support this by default: it doesn't make much sense. You are serializing an instance, and static or const members are not logically part of an instance but of the class as a whole.

That said, you can still serialize static member if it's a property:

[JsonProperty]
public static int y { get; set; } // this will be serialized

And of course you can completely override the serializer's behavior by creating a custom JsonConverter.



Related Topics



Leave a reply



Submit