Sunday, April 17, 2011

C# 3.0: Fill in objects with different behaviour in collections

I want to fill items in a combobox, each of them has different behaviour. Yes I know I could simply create 3 classes deriving from a base class. But my question is kind of "is there another way" and "what is possible". In Java one can do "new MyClass(){public void overriddenmethod(){...} }" but in C# we can not, can we?

Now I use a lambda to define a method on the fly but the problem is that I later want the new XxxFormatter() as instance variable of that object. Since the XxxFormatters share no common base class I cannot put them as a single field in the SerializingHelper class.

Do you have any Ideas?

public delegate void SerializingHandler(Stream s, object o);

class SerializingHelper
{
    public string Name { get; set; }
    public SerializingHandler Serializer { get; set; }
}

comboFormat.Items.AddRange(new object[] 
{ 
            new SerializingHelper{ Name = "Binary", 
Serializer = (s,o)=>new BinaryFormatter().Serialize(s,o),

            new SerializingHelper{ Name = "Soap", 
Serializer = (s,o)=>new SoapFormatter().Serialize(s,o), 

            new SerializingHelper{ Name = "Xml", 
Serializer = (s,o)=>new XmlSerializer(typeof(KontaktpartnerData), new Type[]   
 {typeof(ArrayList), typeof(KontaktPartner)}).Serialize(s,o), }

});
From stackoverflow
  • If you just want to prevent instantiating a new serializer instance each time, you can instantiate them outside of the lambda:

    var binaryFormatter = new BinaryFormatter();
    
    comboFormat.Items.AddRange(new object[]
    { 
        new SerializingHelper
        {
            Name = "Binary",
            Serializer = binaryFormatter.Serialize
        }
    
        ...
    });
    


    If you really need to store the formatter as a field, you could do something like this:

    delegate void SerializingHandler<TFormatter>(TFormatter formatter,
                                                 Stream stream,
                                                 object graph);
    
    interface ISerializingHelper
    {
        void Serialize(Stream stream, object graph);
    }
    
    class SerializingHelper<TFormatter> : ISerializingHelper
    {
        private readonly SerializingHandler<TFormatter> handler;
        private readonly TFormatter formatter;
    
        public SerializingHelper(SerializingHandler<TFormatter> handler,
                                 TFormatter formatter)
        {
            this.handler = handler;
            this.formatter = formatter;
        }
    
        public TFormatter Formatter
        {
            get { return this.formatter; }
        }
    
        public void Serialize(Stream stream, object graph)
        {
            this.handler(this.formatter, stream, graph);
        }
    }
    

0 comments:

Post a Comment