Question

Je suis intéressé: quel est l'analogue de C # de std::pair en C ++? J'ai trouvé System.Web.UI.Pair la classe, mais je préférerais quelque chose basé sur des modèles.

Merci!

Était-ce utile?

La solution

Les simples sont disponibles depuis .NET4. 0 et prise en charge des génériques:

Tuple<string, int> t = new Tuple<string, int>("Hello", 4);

Dans les versions précédentes, vous pouvez utiliser System.Collections.Generic.KeyValuePair<K, V> ou une solution semblable à celle-ci:

public class Pair<T, U> {
    public Pair() {
    }

    public Pair(T first, U second) {
        this.First = first;
        this.Second = second;
    }

    public T First { get; set; }
    public U Second { get; set; }
};

Et utilisez-le comme ceci:

Pair<String, int> pair = new Pair<String, int>("test", 2);
Console.WriteLine(pair.First);
Console.WriteLine(pair.Second);

Cette sortie:

test
2

Ou même ces paires chaînées:

Pair<Pair<String, int>, bool> pair = new Pair<Pair<String, int>, bool>();
pair.First = new Pair<String, int>();
pair.First.First = "test";
pair.First.Second = 12;
pair.Second = true;

Console.WriteLine(pair.First.First);
Console.WriteLine(pair.First.Second);
Console.WriteLine(pair.Second);

Cela génère:

test
12
true

Autres conseils

System.Web.UI contenait la classe Pair car elle était fortement utilisée dans ASP.NET 1.1 en tant que structure ViewState interne.

Mise à jour août 2017: C # 7.0 / .NET Framework 4.7 fournit une syntaxe permettant de déclarer un tuple comportant des éléments nommés à l'aide de System.ValueTuple struct.

//explicit Item typing
(string Message, int SomeNumber) t = ("Hello", 4);
//or using implicit typing 
var t = (Message:"Hello", SomeNumber:4);

Console.WriteLine("{0} {1}", t.Message, t.SomeNumber);

voir MSDN pour d'autres exemples de syntaxe.

Mise à jour juin 2012: Tuples font partie de .NET depuis la version 4.0.

Voici un article précédent décrivant l'inclusion dans.NET4.0 . et assistance aux génériques:

Tuple<string, int> t = new Tuple<string, int>("Hello", 4);

Malheureusement, il n'y en a pas. Vous pouvez utiliser le System.Collections.Generic.KeyValuePair<K, V> dans de nombreuses situations.

Vous pouvez également utiliser des types anonymes pour gérer les nuplets, au moins localement:

var x = new { First = "x", Second = 42 };

La dernière alternative consiste à créer une propre classe.

C # a tuples à partir de la version 4.0.

Certaines réponses semblent tout à fait fausses,

  1. vous ne pouvez pas utiliser de dictionnaire pour stocker les paires (a, b) et (a, c). Le concept des paires ne doit pas être confondu avec la recherche associative de la clé et des valeurs
  2. beaucoup du code ci-dessus semble suspect

Voici ma classe de couple

public class Pair<X, Y>
{
    private X _x;
    private Y _y;

    public Pair(X first, Y second)
    {
        _x = first;
        _y = second;
    }

    public X first { get { return _x; } }

    public Y second { get { return _y; } }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;
        if (obj == this)
            return true;
        Pair<X, Y> other = obj as Pair<X, Y>;
        if (other == null)
            return false;

        return
            (((first == null) && (other.first == null))
                || ((first != null) && first.Equals(other.first)))
              &&
            (((second == null) && (other.second == null))
                || ((second != null) && second.Equals(other.second)));
    }

    public override int GetHashCode()
    {
        int hashcode = 0;
        if (first != null)
            hashcode += first.GetHashCode();
        if (second != null)
            hashcode += second.GetHashCode();

        return hashcode;
    }
}

Voici un code de test:

[TestClass]
public class PairTest
{
    [TestMethod]
    public void pairTest()
    {
        string s = "abc";
        Pair<int, string> foo = new Pair<int, string>(10, s);
        Pair<int, string> bar = new Pair<int, string>(10, s);
        Pair<int, string> qux = new Pair<int, string>(20, s);
        Pair<int, int> aaa = new Pair<int, int>(10, 20);

        Assert.IsTrue(10 == foo.first);
        Assert.AreEqual(s, foo.second);
        Assert.AreEqual(foo, bar);
        Assert.IsTrue(foo.GetHashCode() == bar.GetHashCode());
        Assert.IsFalse(foo.Equals(qux));
        Assert.IsFalse(foo.Equals(null));
        Assert.IsFalse(foo.Equals(aaa));

        Pair<string, string> s1 = new Pair<string, string>("a", "b");
        Pair<string, string> s2 = new Pair<string, string>(null, "b");
        Pair<string, string> s3 = new Pair<string, string>("a", null);
        Pair<string, string> s4 = new Pair<string, string>(null, null);
        Assert.IsFalse(s1.Equals(s2));
        Assert.IsFalse(s1.Equals(s3));
        Assert.IsFalse(s1.Equals(s4));
        Assert.IsFalse(s2.Equals(s1));
        Assert.IsFalse(s3.Equals(s1));
        Assert.IsFalse(s2.Equals(s3));
        Assert.IsFalse(s4.Equals(s1));
        Assert.IsFalse(s1.Equals(s4));
    }
}

S'il s'agit de dictionnaires, etc., vous recherchez System.Collections.Generic.KeyValuePair < TKey, TValue >.

En fonction de ce que vous souhaitez accomplir, vous pouvez essayer KeyValuePair .

Le fait que vous ne pouvez pas modifier la clé d'une entrée peut bien sûr être corrigé en remplaçant simplement l'entrée entière par une nouvelle instance de KeyValuePair.

J'ai créé une implémentation C # de Tuples, qui résout le problème de manière générique pour deux à cinq valeurs - voici l'article du blog , qui contient un lien vers la source.

Je posais la même question tout à l’heure, après une rapide recherche sur Google, j’ai découvert qu’il existe une classe de paires dans .NET, à l’exception de la classe System.Web.UI ^ ~ ^ ( http://msdn.microsoft.com/en-us/library/system.web.ui.pair.aspx ) Dieu sait pourquoi ils l'ont mis là au lieu du cadre des collections

Depuis .NET 4.0, vous avez System.Tuple<T1, T2> la classe:

// pair is implicitly typed local variable (method scope)
var pair = System.Tuple.Create("Current century", 21);

J'étend généralement la Tuple classe dans mon propre wrapper générique, comme suit:

public class Statistic<T> : Tuple<string, T>
{
    public Statistic(string name, T value) : base(name, value) { }
    public string Name { get { return this.Item1; } }
    public T Value { get { return this.Item2; } }
}

et utilisez-le comme suit:

public class StatSummary{
      public Statistic<double> NetProfit { get; set; }
      public Statistic<int> NumberOfTrades { get; set; }

      public StatSummary(double totalNetProfit, int numberOfTrades)
      {
          this.TotalNetProfit = new Statistic<double>("Total Net Profit", totalNetProfit);
          this.NumberOfTrades = new Statistic<int>("Number of Trades", numberOfTrades);
      }
}

StatSummary summary = new StatSummary(750.50, 30);
Console.WriteLine("Name: " + summary.NetProfit.Name + "    Value: " + summary.NetProfit.Value);
Console.WriteLine("Name: " + summary.NumberOfTrades.Value + "    Value: " + summary.NumberOfTrades.Value);

Pour que ce qui précède fonctionne (j'avais besoin d'une paire comme clé d'un dictionnaire). Je devais ajouter:

    public override Boolean Equals(Object o)
    {
        Pair<T, U> that = o as Pair<T, U>;
        if (that == null)
            return false;
        else
            return this.First.Equals(that.First) && this.Second.Equals(that.Second);
    }

et une fois que j'ai fait cela, j'ai aussi ajouté

    public override Int32 GetHashCode()
    {
        return First.GetHashCode() ^ Second.GetHashCode();
    }

pour supprimer un avertissement du compilateur.

La bibliothèque PowerCollections (auparavant disponible chez Wintellect mais désormais hébergée sur Codeplex @ http://powercollections.codeplex.com ) a une structure de paire générique.

Outre la classe personnalisée ou .Net 4.0 Tuples, depuis C # 7.0, une nouvelle fonctionnalité appelée ValueTuple est une structure qui peut être utilisée dans ce cas. Au lieu d'écrire:

Tuple<string, int> t = new Tuple<string, int>("Hello", 4);

et accédez aux valeurs via t.Item1 et t.Item2, vous pouvez simplement le faire comme ça:

(string message, int count) = ("Hello", 4);

ou même:

(var message, var count) = ("Hello", 4);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top