2009-03-31 3 views
0

Je souhaite remplir des éléments dans une liste déroulante, chacun d'entre eux ayant un comportement différent. Oui, je sais que je pourrais simplement créer 3 classes dérivant d'une classe de base. Mais ma question est un peu "existe-t-il un autre moyen" et "qu'est-ce qui est possible". En Java on peut faire "new MyClass() {public void overriddenmethod() {...}}" mais en C# on ne peut pas, on peut?C# 3.0: Remplir des objets avec des comportements différents dans les collections

Maintenant j'utilise un lambda pour définir une méthode à la volée mais le problème est que je veux plus tard la nouvelle XxxFormatter() comme variable d'instance de cet objet. Comme les XxxFormatters ne partagent aucune classe de base commune, je ne peux pas les placer comme un seul champ dans la classe SerializingHelper.

Avez-vous des idées?

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

}); 
+0

Pourquoi voulez-vous le formateur comme une variable d'instance de la classe? Qu'est-ce que vous essayez d'atteindre que le code que vous avez donné ne fait pas déjà? –

+0

À l'heure actuelle, chaque fois que l'utilisateur utilise un formateur de la liste déroulante, un nouvel objet formateur est créé, que je veux éviter. Je sais, la performance dans ce scénario spécial n'a pas vraiment d'importance. Additioally si j'insère un désérialiseur en utilisant une propriété supplémentaire, la création du formateur est dupliquée. – codymanix

Répondre

2

Si vous voulez juste pour éviter l'instanciation d'une nouvelle instance sérialiseur à chaque fois, vous pouvez les instancier en dehors du lambda:

var binaryFormatter = new BinaryFormatter(); 

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

    ... 
}); 

Si vous avez vraiment besoin de stocker le formatter comme champ, vous pouvez faire quelque chose comme ceci:

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); 
    } 
} 
Questions connexes