如何分隔 C# 元组值以匹配方法参数
How to separate C# tuple values to match method arguments
我想知道是否可以 'spread' 元组的值以正确匹配方法参数的方式。
例如:
public (int, object) GetTuple() {
return (5, null);
}
public void ReceiveMultipleArguments(int a, object b) { ... }
ReceiveMultipleArguments方法的调用是这样的:
ReceiveMultipleArguments(GetTuple());
将导致此错误:
CS7036: There is no argument given that corresponds to the required formal parameter 'b' of 'Method1(int, object)'
可能的解决方案是手动解构元组,然后将每个值作为方法参数提供,但是有没有办法让它更短,例如 javascript 中存在的 spread operator?
也许这对你有帮助:
static void Main(string[] args)
{
ReceiveMultipleArguments(GetTuple());
Console.WriteLine();
}
public static (int, object) GetTuple()
{
return (5, null);
}
public static void ReceiveMultipleArguments((int, object) p)
{
Console.WriteLine(p.Item1);
Console.WriteLine(p.Item2);
}
C# 是强类型语言,所以你不能传递元组(它有自己的 class ValueTuple
class)。
因此您可以只为方法定义重载:
public void Test()
{
ReceiveMultipleArguments(GetTuple());
}
public (int, object) GetTuple()
{
return (5, null);
}
public void ReceiveMultipleArguments((int a, object b) @params) => ReceiveMultipleArguments(@params.a, @params.b);
public void ReceiveMultipleArguments(int a, object b) { ... }
您可以更改方法的签名以支持 params
个 object
个元素。然后你可以将元组解压成单独的元素并将其用作参数。
public void Main()
{
var tuple = GetTuple();
var items = UnpackTuple(tuple).ToArray();
DoSomethingWith(items);
}
public void DoSomethingWith(params object[] data)
{
foreach (var d in data)
{
Console.WriteLine(d);
}
}
public IEnumerable<object> UnpackTuple(ITuple tuple)
{
for (var index = 0; index < tuple.Length; index++)
{
yield return tuple[index];
}
}
public ITuple GetTuple()
{
return Tuple.Create(5, "second", 2.489, 'G');
}
但是,如果您需要在程序中移动元组,我强烈建议您放弃元组。根据经验,我已经看到这将导致代码库混乱,难以理解和更改。
相反,为您的元组定义 classes。比方说你需要传递一个对象,比方说一个苹果,以及有多少苹果的计数到某个方法中。 class 可以是通用的 class 例如:
public class CountOf<T>
{
public CountOf(T value, int count)
{
this.Value = value;
this.Count = count;
}
public T Value { get; }
public int Count { get; set; }
}
或非泛型,如:
public class CountedObject
{
public CountedObject(object obj, int count)
{
this.Object = obj;
this.Count = count;
}
public object Object { get; }
public int Count { get; set; }
}
用例:
public void Main()
{
var apple = new Apple();
var countedApples = new CountOf<Apple>(apple, 10);
DoSomethingWith(countedApples);
var countedObject = new CountedObject(apple, 10);
DoSomethingWith(countedObject);
}
public void DoSomethingWith(CountOf<Apple> countedApples)
{
// do something here
}
public void DoSomethingWith(CountedObject countedObject)
{
// do something here
}
public class Apple { }
public class CountOf<T>
{
public CountOf(T value, int count)
{
this.Value = value;
this.Count = count;
}
public T Value { get; }
public int Count { get; set; }
}
public class CountedObject
{
public CountedObject(object obj, int count)
{
this.Object = obj;
this.Count = count;
}
public object Object { get; }
public int Count { get; set; }
}
我想知道是否可以 'spread' 元组的值以正确匹配方法参数的方式。
例如:
public (int, object) GetTuple() {
return (5, null);
}
public void ReceiveMultipleArguments(int a, object b) { ... }
ReceiveMultipleArguments方法的调用是这样的:
ReceiveMultipleArguments(GetTuple());
将导致此错误:
CS7036: There is no argument given that corresponds to the required formal parameter 'b' of 'Method1(int, object)'
可能的解决方案是手动解构元组,然后将每个值作为方法参数提供,但是有没有办法让它更短,例如 javascript 中存在的 spread operator?
也许这对你有帮助:
static void Main(string[] args)
{
ReceiveMultipleArguments(GetTuple());
Console.WriteLine();
}
public static (int, object) GetTuple()
{
return (5, null);
}
public static void ReceiveMultipleArguments((int, object) p)
{
Console.WriteLine(p.Item1);
Console.WriteLine(p.Item2);
}
C# 是强类型语言,所以你不能传递元组(它有自己的 class ValueTuple
class)。
因此您可以只为方法定义重载:
public void Test()
{
ReceiveMultipleArguments(GetTuple());
}
public (int, object) GetTuple()
{
return (5, null);
}
public void ReceiveMultipleArguments((int a, object b) @params) => ReceiveMultipleArguments(@params.a, @params.b);
public void ReceiveMultipleArguments(int a, object b) { ... }
您可以更改方法的签名以支持 params
个 object
个元素。然后你可以将元组解压成单独的元素并将其用作参数。
public void Main()
{
var tuple = GetTuple();
var items = UnpackTuple(tuple).ToArray();
DoSomethingWith(items);
}
public void DoSomethingWith(params object[] data)
{
foreach (var d in data)
{
Console.WriteLine(d);
}
}
public IEnumerable<object> UnpackTuple(ITuple tuple)
{
for (var index = 0; index < tuple.Length; index++)
{
yield return tuple[index];
}
}
public ITuple GetTuple()
{
return Tuple.Create(5, "second", 2.489, 'G');
}
但是,如果您需要在程序中移动元组,我强烈建议您放弃元组。根据经验,我已经看到这将导致代码库混乱,难以理解和更改。
相反,为您的元组定义 classes。比方说你需要传递一个对象,比方说一个苹果,以及有多少苹果的计数到某个方法中。 class 可以是通用的 class 例如:
public class CountOf<T>
{
public CountOf(T value, int count)
{
this.Value = value;
this.Count = count;
}
public T Value { get; }
public int Count { get; set; }
}
或非泛型,如:
public class CountedObject
{
public CountedObject(object obj, int count)
{
this.Object = obj;
this.Count = count;
}
public object Object { get; }
public int Count { get; set; }
}
用例:
public void Main()
{
var apple = new Apple();
var countedApples = new CountOf<Apple>(apple, 10);
DoSomethingWith(countedApples);
var countedObject = new CountedObject(apple, 10);
DoSomethingWith(countedObject);
}
public void DoSomethingWith(CountOf<Apple> countedApples)
{
// do something here
}
public void DoSomethingWith(CountedObject countedObject)
{
// do something here
}
public class Apple { }
public class CountOf<T>
{
public CountOf(T value, int count)
{
this.Value = value;
this.Count = count;
}
public T Value { get; }
public int Count { get; set; }
}
public class CountedObject
{
public CountedObject(object obj, int count)
{
this.Object = obj;
this.Count = count;
}
public object Object { get; }
public int Count { get; set; }
}