views:

178

answers:

3

Yes, the title doesn't make much sense, but here's my situation.

I have two interfaces, say IGen and ITrans. Some of my classes implement IGen, some implement ITrans and some implement both

ITrans has one method (Translate) and IGen has one method (Generate). For the classes that implement both ITrans and IGen Generate simply calls Translate.

I also have an Interface IGenAndTrans which is simply defined as

public interface IGenAndTrans : IGen , ITrans
{        
}

And I have a class (call it Holder) which has IGenAndTrans as a property.

[Serializable] //<- Problem
public class Holder
{
    public IGenAndTrans GeneratorAndTranslator { get; set;}
}

Now, I want to mark the class Holder with [SerializableAttribute] and use the XmlSerializer. However I can't do this because Holder has a property which is an interface. Normally the recommended approach would be to make IGenAndTrans an abstract base class and use XmlInclude. I've done this successfully in the past.

However I'm unsure of how to do that in this case. Because a lot of my classes implement both IGen and ITrans they can't simply inherit from an abstract base class. This would mean I would need to split each of those classes into two classes with the corresponding duplication of code (since Generate calls Translate a lot of the time)

Any recommendations (if I've managed to explain myself well enough)? Maybe I'm too close to the code and should be implementing it differently.

A: 

Hi Ray, since this is an autoproperty, perhaps you could use [field: NonSerialized] to indicate that the backing field is not serialized?

Andrew Matthews
see remarks here: http://msdn.microsoft.com/en-us/library/system.nonserializedattribute.aspx
Andrew Matthews
but I need to serialize it.
Ray
A: 

I guess this is cheating because I have inside information, but I managed a bit of a specialized fix for myself.

I realised that everything that implemented IGen also implemented ITrans. And I realised that in every class that implemented both interfaces Generate always called Translate.

So I made a base abstract class GenerateAndTranslate that has one property called Translator and one called Generator. They both are of a new type called TranslatorBase that everything that previously implemented ITrans inherits from.

This fix only works in my case, so I'm still interested in hearing other people's ideas.

Ray
A: 

I was gonna to answer your question, but realized there are really not enough information/context on this problem to come up with a solid suggestion.

But the general idea is: store the data, not the methods.

For example, if you have Tiger class and Wolf class, you should refer to them as Animal instead of IWalk; on the other hand, if you have Tiger class and Robot class, you might have to refer to them as object, even though they share IWalk interface.

You should only refer to objects as interfaces when you don't care about the data but the methods.

On an unrelated note, in C# world, there seem to be tendency to strong type everything (which is understandable, since it provides type-safety and compile-time error checking), but there is always opportunity to use generic types and cast them on the fly.

Bill Yang