Has the design of marker interfaces like Java's Serializable or Cloneable evolved in C#?
Asked Answered
A

5

2

Java provides java.io.Serializable and java.lang.Cloneable in his standard library (and special support for it in the language and the JVM) for tasks around deserializing/serializing/cloning.

Has C# chosen a different path to provide this functionality, how does the implementation and code using it differ from Java and why was it done this way?

As an example, why does C# use both an attribute (annotation) and an interface for serialization?

Arri answered 11/6, 2011 at 19:7 Comment(1)
C# provides a number of serialization options -- e.g. ISerializable (marker), or [DataContract] and [Serializable] (attributes), etc. All cases require that the serializer knows how to "read" that kind of class/object but fundamentally it's not that much different.Conductivity
B
3

.NET doesn't use ISerializable as just a marker interface. It acts not only as a marker, but also allows you to control exactly how .NET will serialize the class by implementing GetObjectData and a constructor which takes the suitable arguments.

The attribute is used when the class can be serialized, but you don't want to define your own serialization behavior.

So: Use ISerializable when you want to define your own serialization behavior; or use the [Serializable] attribute when you want to leave it up to the serialization formatter.

Would I call it evolution? I don't know. .NET is just offering you different degrees of flexibility.

Barrow answered 11/6, 2011 at 19:36 Comment(2)
OK, thanks for the correction. I looked in the MSDN documentation and didn't see that GetObjectData was defined on ISerializable (it appears when .NET 4.0 is selected, but not when .NET 3.5/2.0 is selected). I assumed its behaviour is still comparable to Serializable in Java, where it doesn't "officially" define a method, but will look for some methods with specific names with a bit of VM magic? Afaik this was done so it doesn't require the JVM-equivalent of GetObjectData to be public.Arri
The MSDN documents on that particular page are wrong. The GetObjectData method has been there the whole time. Since it is on an interface, it has to be public for C#, as that is the point of the contract. From the .NET framework 1.0, that has been the purpose of ISerializable: to implement that method to control serialization. Here is another page that documents that correctly: msdn.microsoft.com/en-us/library/…Barrow
J
2

if you want something about serialization: check this

Janitajanith answered 11/6, 2011 at 19:12 Comment(0)
D
2

I do not think C# has evolved. Rather, they fixed both things:

  • Serialization in Java is not very clean: deserialization involves object "creation" without calling a constructor, the whole process can include the runtime calling private methods, etc. check the specs if you are curious.

  • Cloneable is just plain broken. It should not be a marker interface, but specify the clone() method. As it is you have Cloneables you cannot clone().

Basically, there are lots of things in Java, mainly from the pre 1.2 days, that are quite broken/messed up/unclean/whatever.

Dichogamy answered 11/6, 2011 at 23:2 Comment(0)
C
1

Not sure what you mean by 'evolved', if anything I think the trend is toward attributes rather than marker interfaces. I don't know if Java has gone that way lately as well.

Serialization in the CLR for example is evidenced in its most basic form with attributes, although you can implement a few non-marker interfaces that give you more control over the process if you need it.

Corbie answered 11/6, 2011 at 19:16 Comment(0)
O
1

Marker interfaces are probably one of the worst decisions ever implemented in Java. I mean just look at how useless Cloneable turned out to be, because nobody defined a public clone() method in the interface.

.NET not going into that direction (at least I'm not aware of any interfaces in that direction) is less of an evolution and more an abandonment of the whole notion. Another direction that seems to be taken more and more seems to be annotations, which I assume you could see as a "marker" but on a more basic level (eg I'm pretty sure if Java was implemented today transient would be an annotation and not a qualifier)

Orangutan answered 11/6, 2011 at 20:40 Comment(5)
Yes, in Scala transient is finally an annotation (just like @throws, @native, @volatile,... see scala-lang.org/node/106). @serializable was abandoned in favor of scala.Serializable (extending java.io.Serializable though...Arri
@Soc Interesting to know. Any links to why they decided to go with an interface for Serializable instead of an annotation (I mean it'd be a bit more work creating the java bytecode, but since they're doing something similar for fields/methods already that seems not the big problem) - maybe I should ask a question about that.. interesting concept of when to use interfaces/annotations on class level.Orangutan
Sure, go ahead and create a question. That would be a great thing to ask. Afaik this had something to do with java compatibility ... Edit: Found it! scala-programming-language.1934581.n4.nabble.com/…Arri
Ah compatibility still. In my mind I assumed scala created java code and replaced the annotations with the basic java types/interfaces before giving it to the compiler in which case this wouldn't be such a problem - not implemented that way it seems ;)And about the interfaces vs. annotations this thread makes some points, although I think it's a bit too implementation specific and less open than what I'd have in mindOrangutan
Yes, that's basically what they do. But it seems that the types are processed before looking at annotation assuming that annotations can't change the type hierarchy. But exactly this is the case here. Fixing it would have required intermixing annotation-processing and type-processing code more deeply, which was rejected because it would have considerably complicated the compiler code.Arri

© 2022 - 2024 — McMap. All rights reserved.