views:

268

answers:

1

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), }

});
+2  A: 

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);
    }
}
dtb