web-dev-qa-db-fra.com

Comment initialiser l'objet KeyValuePair de la bonne façon?

J'ai vu dans (entre autres) cette question que les gens se demandent comment initialiser une instance de KeyValuePair , qui devrait normalement ressemble à ca.

KeyValuePair<int, int> keyValuePair = new KeyValuePair<int, int>
{ 
  Key = 1,
  Value = 2
};

Cela ne fonctionne pas, comme si les propriétés n'étaient pas là. Au lieu de cela, j'ai besoin d'utiliser le constructeur comme ça.

KeyValuePair<int, int> keyValuePair = new KeyValuePair<int, int>(1, 2);

Certes, la syntaxe est plus courte mais cela me dérange de ne pas pouvoir utiliser l'initialiseur. Qu'est-ce que je fais mal?

44
user1672517

Vous ne vous trompez pas, vous devez initialiser un keyValuePair en utilisant

KeyValuePair<int, int> keyValuePair = new KeyValuePair<int, int>(1, 2);

La raison pour laquelle vous ne pouvez pas utiliser la syntaxe d'initialisation d'objet, c'est-à-dire {Key = 1, Value = 2}, c'est parce que les propriétés Key et Value n'ont pas seulement de setters getters (elles sont en lecture seule). Vous ne pouvez donc même pas faire:

keyValuePair.Value = 1; // not allowed
51
Kevin Holditch

KeyValuePair<int, int> est un struct, et, heureusement, c'est immuable struct. En particulier, cela signifie que ses propriétés sont en lecture seule. Vous ne pouvez donc pas utiliser l'intialiseur d'objet pour eux.

14
Dennis

Ok vous avez les réponses. Comme alternative, je préfère le modèle d'usine similaire à la classe Tuple, pour la magie d'inférence de type :)

public static class KeyValuePair
{
    public static KeyValuePair<K, V> Create<K, V>(K key, V value)
    {
        return new KeyValuePair<K, V>(key, value);
    }
}

Si court devient plus court:

var keyValuePair = KeyValuePair.Create(1, 2);
10
nawfal

Les dictionnaires ont des initialiseurs compacts:

var imgFormats = new Dictionary<string, ChartImageFormat>()
{
    {".bmp", ChartImageFormat.Bmp}, 
    {".gif", ChartImageFormat.Gif}, 
    {".jpg", ChartImageFormat.Jpeg}, 
    {".jpeg", ChartImageFormat.Jpeg}, 
    {".png", ChartImageFormat.Png}, 
    {".tiff", ChartImageFormat.Tiff}, 
};

Dans ce cas, le dictionnaire utilisé pour associer les extensions de fichier aux constantes de format d'image des objets graphiques.

Une seule paire valeur/clé peut être renvoyée par le dictionnaire comme ceci:

var pair = imgFormats.First(p => p.Key == ".jpg");
9
flodis

Les propriétés Key et Value n'ont pas de setters. C'est pourquoi vous ne pouvez pas les utiliser dans l'initialiseur. Utilisez simplement le constructeur :) et tout ira bien.

5
Mihail Shishkov

Voici un exemple qui fait le travail

KeyValuePair<int, int> kvp = new KeyValuePair<int, int>(1, 1);
2
Paulo Carvalho

Les propriétés Key et Value sont en lecture seule, vous ne pouvez donc pas les utiliser dans un initialiseur d'objet.

Voir cette entrée dans le guide de programmation C # .

1
Phil

Vous ne faites pas quelque chose de mal. Les propriétés KeyValuePairs sont en lecture seule. Vous ne pouvez pas les définir. De plus, il n'y a pas de constructeur par défaut vide. Vous devez utiliser le constructeur fourni.

1
nvoigt