serializable to derived classes - c#

Is there an easy way to enforce a derived class must be serialiable?
Suppose I define a interface that needs the derived classes to be serializable. According to this post, I cannot just specify the serializable attribute in the interface, because derived classes don't need to respect that.
I believe I could have the interface inherit from the ISerializable interface, but does that mean that the derived class couldn't use the attribute to specify serialization (as opposed to actually implementing the methods for ISerializable)?

We cannot use [Serializable] as
gives error with an interface.
We may use [Serializable] attribute
with base class but even then this
attribute is not inherited. This does
not seem possible.
Have a look a this link as well.
Enforcing serializable from an
interface without forcing classes to
custom serialize in C#.

Related

Why an interface cannot be serialized? [duplicate]

I would think that adding that attribute to an interface would be helpful make sure you do not create classes that use the interface and forget to make them serializable.
This could be a very fundamental question, but I wanted to ask the experts.
Interfaces define a contract and do not have any state of their own.
Serialization is about saving and loading state into and out of an object model.
Not much point to serializing something that holds no state.
To answer the practical question of forcing an implementation of an interface to be Serializable - this is why the ISerializable interface exists.
In .NET you can declare an interface that should implement other interfaces:
interface MustBeSerializable : ISerializable {}
See some more information here.
If you want to force classes that implement your custom interface IMyInterface to be serializable you can define it has:
interface IMyInterface : ISerializable
{
// Custom interface definition
}
This more clearly indicates that the implementing class should support serialization. This does not remove the need to mark the class with the [Serializable] attribute.
IIRC, you can also create a FxCop custom rule that checks that classes that inherit from IMyInterface are marked with the respective [Serializable] attribute and this way removing the need to classes implement custom serialization.
There are some good albeit esoteric reasons behind what an interface is and isn't which keeps this from being possible. That said however: I agree with you. There are many things that would be useful if we could incorporate them into interfaces. [Serializable] and statics come to mind.
Although they do not fit into the philosophy of what an interface is, they seem to incorporate this vacant grey area in single-inheritance OOP. There are of course work arounds but they feel very forced compared to the original intent.
Well, there is a reason that new classes are not marked as serializable by default: By adding the Serializable attribute, you acknowledge that you have ensured that serialization in your class works, by choosing proper data types for your instance fields and by adding serialization logic, if necessary.
So, if you "forgot" to add the Serializable attribute to your class, you most probably also forgot to check whether serialization really works on your class. Granted, in many cases it will work "out of the box", so adding the attribute is all that remains, but you are supposed to double-check and explicitly acknowledge that fact (by manually adding the attribute).

Inherit from abstract class in WCF without exposing that class

I have various classes which I want to expose as Complex Types in WCF, so I add [DataContract] and [DataMember] attributes as necessary on those types and properties.
However if I want to have them inherit from an abstract base class (for example Person inherits from abstract EntityBase), I get an error that the type "cannot inherit from a type that is not marked with DataContractAttribute or SerializableAttribute".
The problem is, if I add [DataContract] attribute to the base class, then that base class is exposed to the client via the WSDL. Not a huge deal I guess, but I would prefer my client doesn't know about my internal implementation.
If I add the [Serializable] attribute to the base class, then it seemed to work at first (it could be serialized but EntityBase was not referenced in the WSDL), but now if I add any properties to EntityBase then it will also complain that its properties are not serializable. (For example I add an ICollection then I get an error that RuleViolation is not serializable).
Unfortunately there seems to be no analogue to [IgnoreDataMember] for a [Serializable] type ([NonSerialized applies only to fields, not properties).
So basically I want to declare this base type but don't need any of its members to be serialized; is there any way to set this up in WCF so the client doesn't see this base type?
Did you try not marking your entities with [DataContract] and [DataMember] at all (so that default serialization is used) and instead marking base class properties with [IgnoreDataMember]?
You always have several choices and I'm afraid you will not like any of them.
Create a set of DTO objects and convert entities to DTO. This is generally a best practice if you want to hide your inner implementation.
Create a surrogate class (implement IDataContractSuroggate) for each entity so that you have control over serialization - I'm not sure if this avoids the problem.
Upgrade to .NET 4.0 and use EF with POCO classes (with no EntityBase as parent)
Best regards, Ladislav
I think you have to use the KnownType attribute.
For instance see WCF issues with KnownType for Dictionary
[EDIT] A more complete discussion of this problem and its solution can be found here:
WCF: Interfaces, Generics and ServiceKnownType

Why are interfaces not [Serializable]?

I would think that adding that attribute to an interface would be helpful make sure you do not create classes that use the interface and forget to make them serializable.
This could be a very fundamental question, but I wanted to ask the experts.
Interfaces define a contract and do not have any state of their own.
Serialization is about saving and loading state into and out of an object model.
Not much point to serializing something that holds no state.
To answer the practical question of forcing an implementation of an interface to be Serializable - this is why the ISerializable interface exists.
In .NET you can declare an interface that should implement other interfaces:
interface MustBeSerializable : ISerializable {}
See some more information here.
If you want to force classes that implement your custom interface IMyInterface to be serializable you can define it has:
interface IMyInterface : ISerializable
{
// Custom interface definition
}
This more clearly indicates that the implementing class should support serialization. This does not remove the need to mark the class with the [Serializable] attribute.
IIRC, you can also create a FxCop custom rule that checks that classes that inherit from IMyInterface are marked with the respective [Serializable] attribute and this way removing the need to classes implement custom serialization.
There are some good albeit esoteric reasons behind what an interface is and isn't which keeps this from being possible. That said however: I agree with you. There are many things that would be useful if we could incorporate them into interfaces. [Serializable] and statics come to mind.
Although they do not fit into the philosophy of what an interface is, they seem to incorporate this vacant grey area in single-inheritance OOP. There are of course work arounds but they feel very forced compared to the original intent.
Well, there is a reason that new classes are not marked as serializable by default: By adding the Serializable attribute, you acknowledge that you have ensured that serialization in your class works, by choosing proper data types for your instance fields and by adding serialization logic, if necessary.
So, if you "forgot" to add the Serializable attribute to your class, you most probably also forgot to check whether serialization really works on your class. Granted, in many cases it will work "out of the box", so adding the attribute is all that remains, but you are supposed to double-check and explicitly acknowledge that fact (by manually adding the attribute).

Custom Serialization of base class properties

I have a class that is implementing the ISerializable interface for custom serialization. This works great for the properties in this class but the class is a derived class. The problem i'm running into is that the base class properties aren't serialized for me. The base class has the serializable attribue but doesnt implement ISerializable. Is there a way to serialize the base class properties without having to add all of them manually in the derived class's ISerializable .GetObjectData method?
From MSDN
As I mentioned, the ISerializable interface is extremely powerful since it allows a type to take complete control over how instances of the type get serialized and deserialized. This power comes at a cost; the type is now responsible for serializing all of its base type's fields as well. Serializing the base type's fields is easy if the base type also implements the ISerializable interface—you just call the base type's GetObjectData method. Someday you may find yourself defining a type that needs to take control of its serialization, but whose base type does not implement the ISerializable interface. In this case, your class must manually serialize the base type's fields.

Exact use of Abstract class

What is the exact use of an Abstract class? Is not possible to do the same things in an ordinary class as it is an an abstract class?
Use an abstract class to provide some concrete implementation but not allow instantiation. You can always instantiate an ordinary class which doesn't make sense if it can't stand alone. At the same time, an interface might not be enough if there's a concrete implementation that's identical in all implementing classes. An abstract class is just enough.
Interface: contract only, no implementation, no instantiation
Abstract class: contract, some implementation, no instantiation
Class: contract, implementation, instantiation
An abstract class is used when you have some base functionality that you want subclasses to inherit, but it wouldn't make sense to instantiate the base class. For example, if you had something like a Shape base class, you could have some built in implementation that could be used by subclasses as well as interface methods that you want the subclasses to implement. However, it probably wouldn't make sense to create a Shape object. An abstract class gives you this functionality. Another great example of abstract class uses is the abstract factory pattern.
Regular classes require you to provide implementations for all methods.
Interfaces require you to not provide any implementations for all methods.
Abstract classes are the only type of class that allow you to both have methods that do contain an implementation, and have methods that do not provide an implementation, but require an inheriting class to provide one.
The fact that you are allowed to add methods without an implementation is the reason you cannot instantiate an abstract class: you can only instantiate something that has implementations for all its methods.
Unlike regular classes, abstract classes can contain abstract methods. They act much like interface members.
Meanwhile, they can do just about everything else that regular classes can do: they can implement methods, contain fields & nested types, derive from another class, etc.

Categories

Resources