mai
2007
Comme le dit le nom « initializer », il n’est possible d’utiliser un object initializer que sur l’initailisation de l’objet (ie : à son instanciation). Cela est une restriction car de ce fait, si on passe par une factory, on ne peut pas l’utiliser.
Prenons un exemple concret.
On ajoute un DataSet à un projet. Dans ce DataSet, on met une table « MyTable » avec plusieurs colonnes dont une, « IntCol » de type int qui autorise les DBNull.
Puis on crée une instance de la table et on la remplit. Imaginons maintenant que dans certains cas, on veuille laisser IntCol à DBNull.
Pour rajouter un DataRow à MyTable (ou avec Orcas d’une TypedTableBase<>
), vous pouvez passer par :
myTable.Rows.Add(<<i>liste des valeurs pour chaque colonne précédant IntCol</i>>, DBNull.Value, <<i>liste des valeurs pour chaque colonne suivant IntCol</i>>);
avec myTable une instance de MyTable.
Mais attention, si plus tard vous insérez une colonne dans votre table et que vous oubliez de changer les paramètres de votre Add, vous n’aurez l’erreur qu’à l’exécution si les types des colonnes qui suivent sont différents. Sinon vous n’aurez même pas d’erreur mais un algorythme qui deviendra faux. Pour rappel, ce Add prend en paramètre params object[] values
.
Il est donc plus propre de passer par la méthode myTable.AddMyTableRow
de la classe MyTableDataTable générée par le designer du DataSet. Cette méthode prend soit une MyTableRow (classe générée par le designer du DataSet), soit la liste des paramètres. Cependant, malgré le fait que vous avez précisé que IntCol autorise DBNull, la propriété IntCol de MyTableRow est de type int et non int?. Idem pour la méthode AddMyTableRow. Soit dit en passant, c’est pour cela que sur les DataRow, vous avez une méthode IsNull.
Du fait de la signature de la méthode, impossible de passer par la méthode qui prend en paramètre la liste des arguments.
On pense alors naturellement utiliser l’autre.
Mais là ça se complique. En effet, pour créer une MyTableRow, vous pouvez soit faire un new mais en lui passant un DataRowBuilder en paramètre, soit passer par la méthode myTable.NewRow()
ou mieux myTable.NewMyTableRow()
. La première solution (instancier un MyTableRow) pose un problème, on n’a pas le DataRowBuilder à moins de tricher et d’aller le chercher par réflexion (c’est un champ private de DataTable).
La deuxième solution marche très bien mais n’autorise pas l’utilisation d’un object initialiser car on ne fait pas de new (celui-ci est fait par la méthode appelée). Du coup il va falloir renseigner les propriétés une par une comme dans la préhistoire (le framework 2.0 LOL) !
Rappelons que ceci est vrai aujourd’hui mais que des changements sont possibles d’ici la sortie finale.