I have a very odd exception in my C# app: when trying to deserialize a class containing a generic List<IListMember> (where list entries are specified by an interface), an exception is thrown reporting that "the type ...IListMember is not marked with the serializable attribute" (phrasing may be slightly different, my VisualStudio is not in English).
Now, interfaces cannot be Serializable; the class actually contained in the list, implementing IListMember, is [Serializable]; and yes, I have checked that IListMember is in fact defined as an interface and not accidentally as a class!
I have tried reproducing the exception in a separate test project only containing the class containing the List and the members, but there it serializes and deserializes happily :/
Does anyone have any good ideas about what it could be?
Edit:
We are using a BinarySerializer; and I repeat, when extracted to a test project the class serializes happily. So I do not need a workaround to serialize a class containing a List<IThing>, as in general this works fine (as long as the actual classes implementing IThing are serializable); what I am looking for is reasons why it might not work this particular time...
I have now put in a workaround (serializing each list member individually, together with the number of entries, and recreating the List by hand), but would really like to find out what it could be for future reference.
It doesn't matter that the class backing the interface is serializable. Interfaces cannot be serialized, period.
In order to deserialize, the serializer needs to be able to instantiate a concrete type, and it determines this type by reflecting on the fields/properties of the class-to-be-deserialized.
If the type of one of those properties is an interface, then it will never be able to construct a concrete type to assign to that member. All it sees is the interface, it has no idea which class originally implemented it when the data was serialized.
If you want the class to be serializable, then every class in the object graph must be a concrete type. No interfaces allowed.
(Postscript: Actually, I sort of lied, the BinaryFormatter can serialize/deserialize directly to/from interface types, but I strongly suspect that's not what's being used here.)
The Easy Way (Although ugly) Wrap your list:
public ListMemberCollection : List<IListMember>, ISerializable
{
// Implement ISerializable Here
}
The Alternative Way (Although better) AbstractBaseClass:
[Serializable]
public ListMemberBase : IListMember
{
// Implement abstract versions of everything
}
A possibility?: (On your other class)
class TheClassYoureSerializing
{
[Serializable]
public List<IListMember> list { get; set; }
}
Related
I understand that static methods are not correct for interfaces (see: Why Doesn't C# Allow Static Methods to Implement an Interface?) yet have come up against a situation where I have an object that implements all methods of an interface where all can be static, so I think I must be designing incorrectly.
Trouble is, I cant see any alternative
My interface IDataSerializer is implemented by several classes. One that de/serializes XML, one that does JSON, etc. All of these classes implement the same functions and none have any "state data" (members, etc), but all eventually result in the same type of object being output.
For example, the XML class:
public class MyXmlSerializer : IDataSerializer
{
public string SerializeFoo(object foo)
{
// uses .Net XML serialzer to serialize foo
}
public object DeserializeFoo(string foo)
{
// uses .NET XML serializer to deserialize foo
}
// Object type returned by above methods is only ever
// used by following method which returns a type available
// to all IDataSerializer implementations as this is
// the data actually used by the rest of the program
public IList<Bar> CreateBarList(object deserializedFoo)
{
// does some magic to extract a list of Bar from the
// deserialized data, this is the main work for any
// IDataSerializer implementation
}
}
Obviously all of the methods shown above could be static (they all take in all the info they need as parameters and all return the result of their working, there are no members or fields)... but because they should be implemented in a serializer that can do work for any type of serial data (XML,JSON, YAML, etc) then they form an interface... Which is it? Am I thinking about this wrong? Is there an alternative, specific, pattern for achieving what I want to do?
Afterthought: maybe I should simply change my idea of de/serialization being work that something can do to thinking of each implementation as is a serlializer, thus suggesting replacing interface with abstract class?
After-afterthought: overridden methods can't be static either, so changing to abstract class doesn't help any.
From logical point of view these methods should be static, because they logically don't work on a particular instance and don't use shared resources.This class don't have a state as well. But... from a pragmatic point of view, instant class brings many benefits, like:
class (interface) if fully testable,
follows the OOP and SOLID principles,
can be registered as singleton, so you can create only one instance of this object,
it's easy to add any dependencies to these classes
easy to maintain
some useful design patterns can be applied (e.g. decorator, composite)
can be lazy loaded and disposed in any time
In your case, in my opinion, you should hide this implementation behind the interface and register it as a singleton, e.g.(using autofac)
builder.RegisterType<MyXmlSerializer>().As<IDataSerializer>().SingleInstance();
In addition, if you need to, you can create an extension method for this interface and add static methods to this contract.
More information can be found here:
Instance methods vs static
Static class vs singleton
Extension methods
I am looking at nServiceBus and came over this interface
namespace NServiceBus
{
public interface IMessage
{
}
}
What is the use of an empty interface?
Usually it's to signal usage of a class. You can implement IMessage to signal that your class is a message. Other code can then use reflection to see if your objects are meant to be used as messages and act accordingly.
This is something that was used in Java a lot before they had annotations. In .Net it's cleaner to use attributes for this.
#Stimpy77 Thanks! I hadn't thought of it that way.
I hope you'll allow me to rephrase your comment in a more general way.
Annotations and attributes have to be checked at runtime using reflection. Empty interfaces can be checked at compile-time using the type-system in the compiler. This brings no overhead at runtime at all so it is faster.
Also known as a Marker Interface:
http://en.wikipedia.org/wiki/Marker_interface_pattern
In java Serializable is the perfect example for this. It defines no methods but every class that "implements" it has to make sure, that it is really serializable and holds no reference to things that cannot be serialized, like database connections, open files etc.
In Java, empty interfaces were usually used for "tagging" classes - these days annotations would normally be used.
It's just a way of adding a bit of metadata to a class saying, "This class is suitable for <this> kind of use" even when no common members will be involved.
Normally it's similar to attributes. Using attributes is a preferred to empty interfaces (at least as much as FxCop is aware). However .NET itself uses some of these interfaces like IRequiresSessionState and IReadOnlySessionState. I think there is performance loss in metadata lookup when you use attributes that made them use interfaces instead.
An empty interface acts simply as a placeholder for a data type no better specified in its interface behaviour.
In Java, the mechanism of the interface extension represents a good example of use. For example, let's say that we've the following
interface one {}
interface two {}
interface three extends one, two {}
Interface three will inherit the behaviour of 'one' and 'two', and so
class four implements three { ... }
has to specify the two methods, being of type 'three'.
As you can see, from the above example, empty interface can be seen also as a point of multiple inheritance (not allowed in Java).
Hoping this helps to clarify with a further viewpoint.
They're called "Mark Interfaces" and are meant to signal instances of the marked classes.
For example... in C++ is a common practice to mark as "ICollectible" objects so they can be stored in generic non typed collections.
So like someone over says, they're to signal some object supported behavior, like ability to be collected, serialized, etc.
Been working with NServiceBus for the past year. While I wouldn't speak for Udi Dahan my understanding is that this interface is indeed used as a marker primarily.
Though I'd suggest you ask the man himself if he'd had thoughts of leaving this for future extension. My bet is no, as the mantra seems to be to keep messages very simple or at least practically platform agnostic.
Others answer well on the more general reasons for empty interfaces.
I'd say its used for "future" reference or if you want to share some objects, meaning you could have 10 classes each implementing this interface.
And have them sent to a function for work on them, but if the interface is empty, I'd say its just "pre"-work.
Empty interfaces are used to document that the classes that implement a given interface have a certain behaviour
For example in java the Cloneable interface in Java is an empty interface. When a class implements the Cloneable interface you know that you can call run the clone() on it.
Empty interfaces are used to mark the class, at run time type check can be performed using the interfaces.
For example
An application of marker interfaces from the Java programming language is the Serializable interface. A class implements this interface to indicate that its non-transient data members can be written to an ObjectOutputStream. The ObjectOutputStream private method writeObject() contains a series of instanceof tests to determine writeability, one of which looks for the Serializable interface. If any of these tests fails, the method throws a NotSerializableException.
An empty interface can be used to classify classes under a specific purpose. (Marker Interface)
Example : Database Entities
public interface IEntity {
}
public class Question implements IEntity {
// Implementation Goes Here
}
public class Answer implements IEntity {
// Implementation Goes Here
}
For Instance, If you will be using Generic Repository(ex. IEntityRepository), using generic constraints, you can prevent the classes that do not implement the IEntity interface from being sent by the developers.
I have the following two classes. The ConvertToType<T> class is an existing class and works fine, however when it is used an instance is created each time (via reflection), therefore I am creating a wrapper class to hold all the instances as they are created for efficiency.
public class TypeConverterHelper
{
private IList<ConvertToType<>> types;
}
internal class ConvertToType<T>
{
//snip
}
However, as you can see I need a list of my ConvertToType<T> class, but I can't specify the type as the whole point of these classes is that the type is unknown until runtime. I have researched this issue a fair amount, but without finding a successful solution. I know I could set the generic type to be an object, but there you could get un/boxing issues at some point. Adding an interface/abstract base class which is restricted to a struct looked like a good option, but unfortunately T could be a string, and possibly other custom classes at a later date so that solution doesn't work.
So does anyone have any other solutions/suggestions?
The list type has to be non-generic (since the generic type arguments cannot be predicted), so object would do, but it might be better to use a common non-generic base. Boxing/unboxing does not come into the discussion because ConvertToType is a reference type.
You would of course have to cast the values in the list back to ConvertToType<T> before being able to use them; the implementation could look like this:
public class TypeConverterHelper
{
private IList<object> types;
public ConvertToType<T> GetConverter<T>()
{
return types.OfType<ConvertToType<T>>.FirstOrDefault();
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C# WCF: When is it appropriate to use the KnownType attribute?
Not long ago, we needed in class to create, as part of a project, a C# web client. The teacher instructed us to put the attribute DataContract above each class that will be passed.
Then the teacher told us that if you have some thing like this:
A
/ \
/ \
B C
you need to write class A in the following way:
[DataContract]
[KnownType(typeof(B))]
[KnownType(typeof(C))]
public class A
{
}
Isn't this completly against the idea of polymorphism? why should a class know who inherits the class?
This doesn't really have anything to do with C# and polymorphism; rather with serialization. The WCF infrastructure needs to be able to take something like a byte array off the wire and create an object out of it. If class A is an abstract type, there is no way that object can be instantiated. The framework needs to know what types it might receive over the wire so it can inspect the metadata and instantiate the right type of object.
Put another way, the attributes don't tell the class anything about its inheritors (indeed, the list need not include all inheritors); this is strictly so the framework will know what types it can expect to be asked to construct.
I would add, though, that adding the DataContract and DataMember attributes is not always required. They are available for scenarios where you may want to have more fine grained control, such as excluding a public property from serialization. Usually if the type is serializable it can be passed without the attributes.
The WCF serializer separates out the concept of inheritance from the concept of polymorphism. CLR inheritance only means that the base class members are automatically added to the derived class as far as the serializer is concerned, it does not imply any kind of relationship between the two elements in the XML document. To get polymorphism, you have to explicitly tell the serializer that the XML representation of the derived class is substitutable for the XML representation of the base class.
Personally I find the distinction convenient. I sometimes use CLR inheritance without KnownType to add common properties onto classes without implying any kind of business relationship between them.
First of all, as Daniel Says, you are talking about Windows Comunication Fundation (WCF) , not web.
By decorating the class, you are telling to the client that there two classes that he must know to use the class "A", for example
[DataContract]
[KnownType(typeof(B))]
[KnownType(typeof(C))]
public class A
{
[DataMember]
private SuperClass myProp;
}
public Class B : SuperClass {}
public Class C : SuperClass {}
Please review this link for more information : MSDN DataContract
I am using an abstract class as a parameter in a web service call. Currently, I am including an XmlInclude of a derived class in the base class, like so:
[XmlInclude(typeof(DerivedClass))]
public abstract class BaseClass
{
}
However, I'd rather not include all of the derived types in the base class.
In http://www.pluralsight.com/community/blogs/craig/archive/2004/07/08/1580.aspx, the author mentions an alternative - writing the attribute above the web method instead, like so:
[WebMethod]
[System.Xml.Serialization.XmlInclude(typeof(DerivedClass))]
public BaseClass getClass() {
return new DerivedClass();
}
However, I'd also like to not put the derived types in the web service either. Is there a way of keeping the attribute in the derived type?
Lets take it as a given that the framework would somehow need to know what types are in the type hiearchy when deserialization occurs, and how those types are represented in xml. It really has no way to infer this information if it is stored in a derived type.
You then have a couple of options:
- use the XmlInclude attribute
- specify the set of allowed types in the XmlSerializer Constructor overload
Now, if you're expecting a subclass to be passed in to the webservice, the webserver controls serialization and deserialization. So the XmlSerializer contstructor is no longer an option.
As you say, you can put the attribute on the webservice method instead of directly on the class. There's a trade-off between keeping your class "pure" and remembering to put those attributes in every place they may be required.
Of course, the real problem appears to be that you are trying to use your business objects as the message format in your webservice layer.
If you really want to keep the "message format" and "business object" responsibilities separate, then have another class (with the full hierarchy) for which the only use is to be used as a webservice parameter. In that case, there's no problem with sticking all the XmlInclude attributes you need, on the base class. Then, when making calls to the webservice, adapt your business object to and from the message format object. This gives you the added benefit of not applying webservice type constraints to the types of your parameters (eg no interfaces as parameters).
Of course, this method isn't as convenient.
In the end, the webservice needs to know what types to expect, or it won't be able to serialize and deserialize them properly.
And yes, this is a long winded explanation of why the answer is no, you can't only keep the attribute in the derived type. I'd love to be wrong though :)
I don't see how in this case. If you are deserializing there is an overload for specify extra types array where you pass in the derived types.