在C#中是否可能将数组转换为元组?类似这样的操作:
var ar = new int[2] {5, 7};
Tuple<int,int> t = Tuple.Create(ar);
现在使用 C# 7.0,你可以创建扩展方法将数组解构为 ValueTuple
,这使得
var (p1,p2,p3) = s.Split(':');
可能的。
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
在使用时是否会隐式调用?例如,由于LHS是(p1,p2,p3)
,它会检查类是否具有带有3个out
参数的方法或扩展方法,还是需要调用类似于s.Split(':').Deconstruct();
这样的语法? - Jeppevar arr = new[] { 1, 2, 3 }; var (a1,a2,a3) = arr;
会隐式调用 Deconstruct<T>(this T[] srcArray, out T a0, out T a1, out T a2)
。 - NetMageSystem.Tuple
有一个最大的大小限制,这是有充分理由的。它显然不适合你所要做的工作。为什么不返回数组而不是元组呢?你的方法可能需要一个包含数十个元素的元组,这是荒谬的,并且难以维护。ICollection<T>
或 IEnumerable<T>
。那我们为什么不这样做呢?
public static Tuple<T, T> CreateTuple<T>(T[] array, int totalItem = 2)
{
if (arr.length % totalItem != 0)
throw new Exception("Error the length dose not consist with totalItem");
return Tuple.Create(arr);
}
在这里,我们验证每个项目是否具有一个和两个。
错误 CS0029:无法隐式转换类型'System.Tuple<T[]>'到'System.Tuple<T,T>'
- Joerg var ar = new int[2] { 5, 7 };
List<Tuple<int>> result = ar
.Select(x => Tuple.Create(x))
.ToList();
或者如果你想要将它放在一个元组中:
var ar = new int[2] { 5, 7 };
Tuple<int[]> result = Tuple.Create(ar);
Tuple<int, int> tuple = Tuple.Create(ar[0], ar[1]);
你可以像这样使用子元组,比如:
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])
)
你的想法不太好...在C#/.NET中,数组和元组不能“混合使用”。有些语言中,数组和类之间的距离很小(比如Javascript,你可以使用[...]
运算符同时使用数组和对象)。但C#不是这样的语言。Tuple
正是因为这个原因没有定义this[int n]
索引器。
但既然你要代码,那我就给你代码。
主要问题在于数组的大小(以及Tuple<>
的大小)必须在编译时知道:在你写的代码中,你明确地写了Tuple<int, int>
。你可以轻松创建一个方法,给定一个包含两个(或更多)元素的数组,返回一个Tuple<T, T>
,例如:
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]);
}
CreateTuple3()
,CreateTuple4()
...TTuple CreateTuple<TTuple>(object[] vals)
,以类似的方式工作,并以类似的方式发出邪恶的笑声(只需调用CreateTuple<Tuple<int,string,int,...>..)或(...)。 - quetzalcoatlvar (p1,p2,p3) = str.Split(':');
。 - NetMagevar (s1,s2) = unpack("A4x2A4", test);
- NetMage
ar[0],ar[1]
的值即可。 - michip96C#7
可以这样做:(int a, int b) = (ar[0], ar[1]);
(这种方式的优点是可以为元组元素命名)。 - Matthew WatsonTuple<>
的大小)必须在编译时知道:在你编写的代码中,你明确地写了Tuple<int, int>
。你可以轻松创建一个方法,给定一个包含两个(或更多)元素的数组,返回一个Tuple<T, T>
。 - xanatos