HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

A Covariant Tuple

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
tuplecovariantstackoverflow

Problem

I was searching for a way to put a Tuple into a Tuple, and I found that Tuple has no covariance.

  • Is C# 4.0 Tuple covariant



  • Co/Contravariance? Tuple> not satisfied with List



I decide to make my own implementation of an interface which subclass a tuple with a support for Covariance:

/// 
/// A wrapper around Tuple for gaining covariance
/// 
public static class ITuple
{
    private class _ITuple : Tuple, ITuple { public _ITuple(T1 item1) : base(item1) { } }
    public static ITuple Create(T1 item1) { return new _ITuple(item1); }

    private class _ITuple : Tuple, ITuple { public _ITuple(T1 item1, T2 item2) : base(item1, item2) { } }
    public static ITuple Create(T1 item1, T2 item2) { return new _ITuple(item1, item2); }

    private class _ITuple : Tuple, ITuple { public _ITuple(T1 item1, T2 item2, T3 item3) : base(item1, item2, item3) { } }
    public static ITuple Create(T1 item1, T2 item2, T3 item3) { return new _ITuple(item1, item2, item3); }
}

public interface ITuple { T1 Item1 { get; } }
public interface ITuple { T1 Item1 { get; } T2 Item2 { get; } }
public interface ITuple { T1 Item1 { get; } T2 Item2 { get; } T3 Item3 { get; } }


Some tests and usage:

[TestMethod]
public void TestCompile()
{
    // no assertion, just test that the compilation work
    ITuple item = ITuple.Create(null);
    ITuple> item2 = ITuple.Create>(null);
}
[TestMethod]
public void TestEqual()
{
    Assert.AreEqual(ITuple.Create(1, Tuple.Create("a")), ITuple.Create(1, Tuple.Create("a")));
    Assert.AreNotEqual(ITuple.Create(1, Tuple.Create("a")), ITuple.Create(1, Tuple.Create("b")));
}


I choose to hide the implementation of the concrete class _ITuple inside the static class, so you have access only to the public and static builder ITuple.Create.

Problems:

-
Subclass and equality support

Subclassing the tuple is easy and there is nothing to do, and this is my concern. Is there something am I missing? I see no reason why equalities and hashcode soul

Solution

-
I think that non-interface types shouldn't be called ISomething. You could just call the static class Tuple and differentiate it from System.Tuple by using a different namespace. Or you could call the class something like TupleEx, though that's not very descriptive.

But the best option is if you could figure out a good name for the type that differentiates it from System.Tuple. I agree that CovariantTuple is quite long, though I don't have any better ideas.

-
I also don't like the name _ITuple, even if it's not publicly visible. I would call it something like TupleImpl. (Again, if you figure out a good name, you could use that here too.)

-
Regarding equality: your ITuples will show as equal to normal Tuples with the same contents. This most likely is what you want, but you should be aware of it.

I don't think there are any other problems with equality or hash codes.

-
Consider not writing everything on a single line. I think it will make the code clearer.

-
It might make sense to add some way to convert System.Tuple to ITuple and back.

Context

StackExchange Code Review Q#35601, answer score: 7

Revisions (0)

No revisions yet.