Saralyn
Saralyn

Reputation: 313

Dynamically create a tuple with all the same type and a known number of elements

I am looking to dynamically create tuples of a given size that have all the same type.

So if I wanted a tuple of strings of size three I would get Tuple<string, string, string>

I have tried both to pass strings into the angle brackets for Tuple like this:

string foo = "string, string, string";
Tuple<foo> testTuple = Tuple<foo>(~parameters~);

and to pass an array of types into the angle brackets like this:

List<Type> types = new List<Type>() {"".GetType(), "".GetType(), "".GetType()};
Tuple<types> testTuple = Tuple<foo>(~parameters~);

Neither one of these worked. Does anyone know how to make the described dynamic tuples?

(The reason I want to do this is to use tuples inside of a dictionary like

Dictionary<Tuple<# strings>, int> testDictionary = new Dictionary<Tuple<x # strings>, int>();

Using tuples here is more useful than HashSets because the comparison in tuples is by components instead of by reference so that if I have

Tuple<string, string> testTuple1 = new Tuple<string, string>("yes", "no");
Tuple<string, string> testTuple2 = new Tuple<string, string>("yes", "no");
Dictionary<Tuple<string, string>, string> testDictionary = new Dictionary<Tuple<string, string>, string>() {
    {testTuple1, "maybe"}
};
Console.WriteLine(testDict[testTuple2]);

it writes "maybe". If you run this same test with HashSets, it throws an error. If there is a better way to accomplish this same thing, that would also be useful.)

Upvotes: 6

Views: 13518

Answers (3)

James Crosswell
James Crosswell

Reputation: 786

You could do something like this using reflection:

    public static object GetTuple<T>(params T[] values)
    {
        Type genericType = Type.GetType("System.Tuple`" + values.Length);
        Type[] typeArgs = values.Select(_ => typeof(T)).ToArray();
        Type specificType = genericType.MakeGenericType(typeArgs);
        object[] constructorArguments = values.Cast<object>().ToArray();
        return Activator.CreateInstance(specificType, constructorArguments);
    }

That will give you a tuple for a variable number of elements.

Upvotes: 6

Quantic
Quantic

Reputation: 1799

"Does anyone know how to make the described dynamic tuples?"

You can just use Tuple.Create(). For a 3-tuple:

var tupleOfStrings = Tuple.Create("string1", "string2", "string3");
var tupleOfInts = Tuple.Create(1, 2, 3);

Upvotes: 1

Denis Krasakov
Denis Krasakov

Reputation: 1568

Make custom type with List<string> inside (or List<T> if you want generic solution)

Override object.Equals: Use Enumerable.SequenceEqual for inner list in your custom class

Override object.GetHashCode() in order to use your type in dictionary

Upvotes: 0

Related Questions