Reputation: 313
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
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
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
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