简体   繁体   English

c#多任务

[英]c# multi assignment

int a, b, n;
...
(a, b) = (2, 3);
// 'a' is now 2 and 'b' is now 3

This sort of thing would be really helpfull in C#. 这种事情在C#中真的很有帮助。 In this example 'a' and 'b' arn't encapsulated together such as the X and Y of a position might be. 在这个例子中,'a'和'b'没有被封装在一起,例如位置的X和Y可能是。 Does this exist in some form? 这是否以某种形式存在?

Below is a less trivial example. 下面是一个不太重要的例子。

(a, b) = n == 4 ? (2, 3) : (3, n % 2 == 0 ? 1 : 2);

Adam Maras shows in the comments that: Adam Maras在评论中表示:

var result = n == 4 ? Tuple.Create(2, 3) : Tuple.Create(3, n % 2 == 0 ? 1 : 2);

Sort of works for the example above however as he then points out it creates a new truple instead of changing the specified values. 然而,当他指出它创建一个新的三元组而不是更改指定的值时,上述示例的工作类型。

Eric Lippert asks for use cases, therefore perhaps: Eric Lippert要求用例,因此可能:

(a, b, c) = (c, a, b); // swap or reorder on one line
(x, y) = move((x, y), dist, heading);
byte (a, b, c, d, e) = (5, 4, 1, 3, 2);
graphics.(PreferredBackBufferWidth, PreferredBackBufferHeight) = 400;

notallama also has use cases, they are in his answer below. notallama也有用例,他们在下面给出了答案。

We have considered supporting a syntactic sugar for tuples but it did not make the bar for C# 4.0. 我们已经考虑过为元组支持一个语法糖,但它没有成为C#4.0的标准。 It is unlikely to make the bar for C# 5.0; 它不太可能成为C#5.0的标准; the C# 5.0 team is pretty busy with getting async/await working right. C#5.0团队非常忙于让异步/等待正常工作。 We will consider it for hypothetical future versions of the language. 我们将考虑该语言的假设未来版本。

If you have a really solid usage case that is compelling, that would help us prioritize the feature. 如果您有一个非常可靠的用例,这将有助于我们确定该功能的优先级。

use case: 用例:

it'd be really nice for working with IObservables, since those have only one type parameter. 使用IObservables非常好,因为它们只有一个类型参数。 you basically want to subscribe with arbitrary delegates, but you're forced to use Action, so that means if you want multiple parameters, you have to either use tuples, or create custom classes for packing and unpacking parameters. 你基本上想要使用任意委托订阅,但是你被迫使用Action,这意味着如果你想要多个参数,你必须使用元组,或者创建自定义类来打包和解包参数。

example from a game: 来自游戏的例子:

public IObservable<Tuple<GameObject, DamageInfo>> Damaged ...

void RegisterHitEffects() {
    (from damaged in Damaged
     where damaged.Item2.amount > threshold
     select damaged.Item1)
    .Subscribe(DoParticleEffect)
    .AddToDisposables();
}

becomes: 变为:

void RegisterHitEffects() {
    (from (gameObject, damage) in Damaged
     where damage.amount > threshold
     select gameObject)
    .Subscribe(DoParticleEffect)
    .AddToDisposables();
}

which i think is cleaner. 我觉得它更清洁。

also, presumably IAsyncResult will have similar issues when you want to pass several values. 另外,当您想要传递多个值时,可能IAsyncResult会有类似的问题。 sometimes it's cumbersome to create classes just to shuffle a bit of data around, but using tuples as they are now reduces code clarity. 有时创建类只是为了改变一些数据是很麻烦的,但是现在使用元组会降低代码的清晰度。 if they're used in the same function, anonymous types fit the bill nicely, but they don't work if you need to pass data between functions. 如果它们在同一个函数中使用,匿名类型很适合该法案,但如果你需要在函数之间传递数据它们不起作用。

also, it'd be nice if the sugar worked for generic parameters, too. 此外,如果糖也适用于通用参数,那就太好了。 so: 所以:

IEnumerator<(int, int)>

would desugar to 会不会去的

IEnumerator<Tuple<int,int>>

The behavior that you're looking for can be found in languages that have support or syntactic sugar for tuples . 您正在寻找的行为可以在具有元组支持或语法糖的语言中找到。 C# is not among these langauges; C#不属于这些语言; while you can use the Tuple<...> classes to achieve similar behavior, it will come out very verbose (not clean like you're looking for.) 虽然你可以使用Tuple<...>类来实现类似的行为,但它会变得非常冗长(不像你正在寻找的那样干净。)

As others already wrote, C# 4 Tuples are a nice addition, but nothing really compelling to use as long as there aren't any unpacking mechanisms. 正如其他人已经写过的那样,C#4元组是一个很好的补充,但只要没有任何解包机制,没有什么真正令人信服的。 What I really demand of any type I use is clarity of what it describes, on both sides of the function protocol (eg caller, calle sides)... like 我真正要求我使用的任何类型的是它所描述的内容的清晰度,在功能协议的两侧(例如来电者,主叫方)......就像

Complex SolvePQ(double p, double q)
{
    ...
    return new Complex(real, imag);
}
...
var solution = SolvePQ(...);
Console.WriteLine("{0} + {1}i", solution.Real, solution.Imaginary);

This is obvious and clear at both caller and callee side. 这在呼叫者和被呼叫者方面都是显而易见的。 However this 不过这个

Tuple<double, double> SolvePQ(double p, double q)
{
    ...
    return Tuple.Create(real, imag);
}
...
var solution = SolvePQ(...);
Console.WriteLine("{0} + {1}i", solution.Item1, solution.Item2);

Doesn't leave the slightest clue about what that solution actually is (ok, the string and the method name make it pretty obvious) at the call site. 在调用站点上不会留下关于该解决方案实际是什么的正确线索(好吧,字符串和方法名称使其非常明显)。 Item1 and Item2 are of the same type, which renders tooltips useless. Item1和Item2属于同一类型,这使得工具提示无效。 The only way to know for certain is to "reverse engineer" your way back through SolvePQ . 唯一可以确定的方法是通过SolvePQ “反向工程”。

Obivously, this is far fetched and everyone doing serious numerical stuff should have a Complex type (like that in the BCL). 显而易见,这是遥不可及的,每个人都在进行严肃的数字化工作,应该有一个复杂的类型(就像在BCL中那样)。 But everytime you get split results and you want give those results distinct names for the sake of readability , you need tuple unpacking. 但是每次你得到拆分结果并且你想为了可读性而给那些结果带来不同的名字,你需要元组解包。 The rewritten last two lines would be: 重写的最后两行是:

var (real, imaginary) = SolvePQ(...); // or var real, imaginary = SolvePQ(...);
Console.WriteLine("{0} + {1}i", real, imaginary);

This leaves no room for confusion, except for getting used to the syntax. 除了习惯语法之外,这没有留下混淆的余地。

Creating a set of Unpack<T1, T2>(this Tuple<T1, T2>, out T1, out T2) methods would be a more idiomatic c# way of doing this. 创建一组Unpack<T1, T2>(this Tuple<T1, T2>, out T1, out T2)方法将是一种更惯用的c#方式。

Your example would then become 那么你的榜样就会成为

int a, b, n;
...
Tuple.Create(2, 3).Unpack(out a, out b);
// 'a' is now 2 and 'b' is now 3

which is no more complex than your proposal, and a lot clearer. 这并不比你的建议复杂,而且更加清晰。

我能想到的最接近的结构是框架版本4.0中的Tuple类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM