Is it possible to convert array to tuple in C#? Something like this:
var ar = new int[2] {5, 7};
Tuple<int,int> t = Tuple.Create(ar);
Is it possible to convert array to tuple in C#? Something like this:
var ar = new int[2] {5, 7};
Tuple<int,int> t = Tuple.Create(ar);
No, System.Tuple
has a maximum size for good reason. It's simply the wrong tool for the job you appear to be doing. Why don't you just return the array instead of a tuple? Your approach could end up needing a tuple with dozens of elements which is beyond ridiculous and not at all maintainable.
Even better instead of returning the array, return an interface such as ICollection<T>
or IEnumerable<T>
.
not at all maintainable
- just what I wanted to say –
Eveliaevelin Now with C# 7.0, you can create extension methods to deconstruct arrays to ValueTuple
, which makes
var (p1,p2,p3) = s.Split(':');
possible.
public static class ArrayExt {
public static void Deconstruct<T>(this T[] srcArray, out T a0) {
if (srcArray == null || srcArray.Length < 1)
throw new ArgumentException(nameof(srcArray));
a0 = srcArray[0];
}
public static void Deconstruct<T>(this T[] srcArray, out T a0, out T a1) {
if (srcArray == null || srcArray.Length < 2)
throw new ArgumentException(nameof(srcArray));
a0 = srcArray[0];
a1 = srcArray[1];
}
public static void Deconstruct<T>(this T[] srcArray, out T a0, out T a1, out T a2) {
if (srcArray == null || srcArray.Length < 3)
throw new ArgumentException(nameof(srcArray));
a0 = srcArray[0];
a1 = srcArray[1];
a2 = srcArray[2];
}
public static void Deconstruct<T>(this T[] srcArray, out T a0, out T a1, out T a2, out T a3) {
if (srcArray == null || srcArray.Length < 4)
throw new ArgumentException(nameof(srcArray));
a0 = srcArray[0];
a1 = srcArray[1];
a2 = srcArray[2];
a3 = srcArray[3];
}
public static void Deconstruct<T>(this T[] srcArray, out T a0, out T a1, out T a2, out T a3, out T a4) {
if (srcArray == null || srcArray.Length < 5)
throw new ArgumentException(nameof(srcArray));
a0 = srcArray[0];
a1 = srcArray[1];
a2 = srcArray[2];
a3 = srcArray[3];
a4 = srcArray[4];
}
public static void Deconstruct<T>(this T[] srcArray, out T a0, out T a1, out T a2, out T a3, out T a4, out T a5) {
if (srcArray == null || srcArray.Length < 6)
throw new ArgumentException(nameof(srcArray));
a0 = srcArray[0];
a1 = srcArray[1];
a2 = srcArray[2];
a3 = srcArray[3];
a4 = srcArray[4];
a5 = srcArray[5];
}
public static void Deconstruct<T>(this T[] srcArray, out T a0, out T a1, out T a2, out T a3, out T a4, out T a5, out T a6) {
if (srcArray == null || srcArray.Length < 7)
throw new ArgumentException(nameof(srcArray));
a0 = srcArray[0];
a1 = srcArray[1];
a2 = srcArray[2];
a3 = srcArray[3];
a4 = srcArray[4];
a5 = srcArray[5];
a6 = srcArray[6];
}
public static void Deconstruct<T>(this T[] srcArray, out T a0, out T a1, out T a2, out T a3, out T a4, out T a5, out T a6, out T a7) {
if (srcArray == null || srcArray.Length < 8)
throw new ArgumentException(nameof(srcArray));
a0 = srcArray[0];
a1 = srcArray[1];
a2 = srcArray[2];
a3 = srcArray[3];
a4 = srcArray[4];
a5 = srcArray[5];
a6 = srcArray[6];
a7 = srcArray[7];
}
}
Deconstruct
implicitly called based on usage? E.g. since LHS is (p1,p2,p3)
, does it then check if the class has a method or extension method with 3 out
parameters or do you need to call something like ´s.Split(':').Deconstruct();`? –
Overshoe Deconstruct
specifically: deconstruct#user-defined-types –
Overshoe var arr = new[] { 1, 2, 3 }; var (a1,a2,a3) = arr;
will call Deconstruct<T>(this T[] srcArray, out T a0, out T a1, out T a2)
implicitly. –
Arty No, System.Tuple
has a maximum size for good reason. It's simply the wrong tool for the job you appear to be doing. Why don't you just return the array instead of a tuple? Your approach could end up needing a tuple with dozens of elements which is beyond ridiculous and not at all maintainable.
Even better instead of returning the array, return an interface such as ICollection<T>
or IEnumerable<T>
.
not at all maintainable
- just what I wanted to say –
Eveliaevelin By doing this you can get an list of tuples but I don't see the reason to do this:
var ar = new int[2] { 5, 7 };
List<Tuple<int>> result = ar
.Select(x => Tuple.Create(x))
.ToList();
Or if you want to have it in one tuple instead:
var ar = new int[2] { 5, 7 };
Tuple<int[]> result = Tuple.Create(ar);
If you know the size do this:
Tuple<int, int> tuple = Tuple.Create(ar[0], ar[1]);
Well why don't we do it like this
public static Tuple<T, T> CreateTuple<T>(T[] array, int totalItem = 2)
{
if (arr.length % totalItem != 0)
throw new Exception("Error the length does not correlate with totalItem");
return Tuple.Create(arr);
}
Here we validate that each item have one and two.
Error CS0029: Cannot implicitly convert type 'System.Tuple<T[]>' to 'System.Tuple<T, T>'
–
Sanskrit you can use sub tuples like, for example this
var tupArray = new Tuple<dynamic,dynamic,dynamic,dynamic,dynamic,dynamic,dynamic,Tuple<dynamic,dynamic>>
(
a[0],a[1],a[2],a[3],a[4],a[5],a[6],new Tuple<dynamic,dynamic>(a[7],a[8])
)
your idea is a bad idea... array and tuples don't "mix" in C#/.NET. There are languages where the distance between arrays and classes is small (like Javascript, where with the [...]
operator you can use both arrays and objects). C# isn't one of those languages. Tuple
s don't define a this[int n]
indexer for exactly this reason.
But you asked for code, and so I'll give you code.
The main problem here is that the size of the array (and the size of the Tuple<>
) must be known at compile time: in the code you wrote, you explicitly wrote Tuple<int, int>
. You can easily create a method that, given an array of two (or more) elements, returns a Tuple<T, T>
, like:
public static Tuple<T, T> CreateTuple2<T>(T[] array)
{
if (array == null || array.Length < 2)
{
throw new ArgumentException(nameof(array));
}
return Tuple.Create(array[0], array[1]);
}
From this you can create other CreateTuple3()
, CreateTuple4()
...
object
or dynamic
and laugh evilishly at future woes of its users (oh, you got object? so just cast it muahahaha). Or create a single TTuple CreateTuple<TTuple>(object[] vals)
that works in a similar way, and laugh evilishly in a similar way (just invoke it CreateTuple<Tuple<int,string,int,... >..).. or, (...) –
Eveliaevelin var (p1,p2,p3) = str.Split(':');
–
Arty var (s1,s2) = unpack("A4x2A4", test);
–
Arty © 2022 - 2024 — McMap. All rights reserved.
ar[0], ar[1]
– DropsondeC#7
you can do this:(int a, int b) = (ar[0], ar[1]);
(which has the advantage that you can name the tuple elements). – JahnckeTuple<>
) must be known at compile time: in the code you wrote, you explicitly wroteTuple<int, int>
. You can easily create a method that, given an array of two (or more) elements, returns aTuple<T, T>
. – Nonsuch