c# multi assignment

微笑、不失礼 提交于 2019-11-29 03:19:10

We have considered supporting a syntactic sugar for tuples but it did not make the bar for C# 4.0. It is unlikely to make the bar for C# 5.0; the C# 5.0 team is pretty busy with getting async/await working right. 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. 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.

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. 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; while you can use the Tuple<...> classes to achieve similar behavior, it will come out very verbose (not clean like you're looking for.)

The closest structure I can think of is the Tuple class in version 4.0 of the framework.

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. What I really demand of any type I use is clarity of what it describes, on both sides of the function protocol (e.g. 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. The only way to know for certain is to "reverse engineer" your way back through SolvePQ.

Obivously, this is far fetched and everyone doing serious numerical stuff should have a Complex type (like that in the 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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!