2009-03-06 11 views
1

Ok. Donc, j'ai une liste de valeurs, et je voudrais faire quelque chose comme ce qui suit:Initialisation d'objet et "idiome de constructeur nommé"

MyObjectValues 
.Select(currentItems=>new MyType() 
{ 
    Parameter1 = currentItems.Value1, 
    Parameter2 = currentItems.Value2 
}); 

Donc, voici le problème. J'ai besoin de l'exemple ci-dessus pour travailler avec des constructeurs nommés, tels que:

MyObjectValues 
.Select(currentItems=>MyType.GetNewInstance() 
{ 
    Parameter1 = currentItems.Value1, 
    Parameter2 = currentItems.Value2 
}); 

Y at-il un moyen de le faire? Fondamentalement, j'ai une méthode statique que j'ai besoin d'appeler pour récupérer l'instance de l'objet, et je voudrais l'initialiser comme ci-dessus.

EDIT: Je n'ai pas un moyen facile de modifier l'interface de MyType à l'heure actuelle, donc l'ajout de nouveaux appels de fonctions (bien que probablement la meilleure approche) n'est pas très pratique pour le moment.

Répondre

1

Malheureusement, il n'y a pas de soutien direct pour cela en C# 3.0. Les initialiseurs d'objet sont uniquement pris en charge pour les appels de constructeur. Cependant, vous pourriez envisager le modèle Builder. Dans mon port Protocol Buffers, je soutiens comme ceci:

MyType foo = new MyType.Builder {Parameter1 = 10, Parameter2 = 20}.Build(); 

Ainsi, votre exemple deviendrait:

MyObjectValues.Select(currentItems => new MyType.Builder 
{ 
    Parameter1 = currentItems.Value1, 
    Parameter2 = currentItems.Value2 
}.Build()); 

Bien sûr, cela signifie que l'écriture du type Builder imbriqué, mais il peut fonctionner assez bien. Si cela ne vous dérange pas MyType être strictement parlant mutable, vous pouvez laisser une API immuable mais faire une instance de Builder immédiatement créer une nouvelle instance de MyType, puis définir les propriétés comme elle va (car elle a accès aux membres privés), et enfin retourner l'instance de MyType dans la méthode Build(). (Il devrait alors "oublier" l'instance, de sorte qu'une autre mutation soit interdite.)

2

Je suis sûr que quelqu'un va penser à une façon intelligente de le faire en pré-C# 4.0, mais je viens de lire Sam Ng's blog post on named parameters in C# 4.0. Cela devrait résoudre votre problème. Il ressemblerait à ceci:

MyObjectValues.Select(currentItems=>MyType.GetNewInstance(
    Parameter1:currentItems.Value1, 
    Parameter2:currentItems.Value2)); 

EDIT

fogot mentionner, ce qui rend ce utile est que vous pouvez définir les valeurs par défaut pour les paramètres, de sorte que vous ne devez pas les transmettre tous. L'article du blog est un bon résumé.

+0

Cela semble utile, quand il arrive. – GWLlosa

1

Mise à jour: diriez-vous d'une usine:

MyObjectValues.Select(currentItems=>MyTypeFactory.GetNewInstance(currentItems.Value1, 
currentItems.Value2)); 


public static class MyTypeFactory 
{ 
    public static MyType GetNewInstance(
     typeofvalue1 value1, 
     typeofvalue2 value2) 
    { 
     return new MyType { Parameter1 = value1, Parameter2 = value2 }; 
    } 
} 
+0

Je n'ai pas un moyen facile de modifier réellement l'implémentation de MyType dans cette instance. – GWLlosa

+0

Avec l'usine, vous n'avez pas besoin de modifier MyType, implémentez uniquement MyTypeFactory –