C # 3.0: заполнить объекты с различным поведением в коллекциях - PullRequest
0 голосов
/ 31 марта 2009

Я хочу заполнить элементы в выпадающем списке, каждый из которых имеет свое поведение. Да, я знаю, что могу просто создать 3 класса, основанных на базовом классе. Но мой вопрос вроде «есть ли другой путь» и «что возможно». В Java можно сделать «new MyClass () {public void overriddenmethod () {...}}», но в C # мы не можем, не так ли?

Теперь я использую лямбду, чтобы определить метод на лету, но проблема в том, что позже я хочу новый XxxFormatter () в качестве переменной экземпляра этого объекта. Поскольку XxxFormatters не имеют общего базового класса, я не могу поместить их как одно поле в классе SerializingHelper.

Есть ли у вас идеи?

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

});

1 Ответ

2 голосов
/ 31 марта 2009

Если вы просто хотите предотвратить создание экземпляра нового экземпляра сериализатора каждый раз, вы можете создать его вне лямбда-выражения:

var binaryFormatter = new BinaryFormatter();

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

    ...
});

Если вам действительно нужно сохранить средство форматирования как поле, вы можете сделать что-то вроде этого:

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