How to create named reference-type tuples?

2019-04-30 01:23发布

The following line creates a named ValueTuple:

var tuple = (a:1, b:2, c:3, d:4, e:5, f:6);  

Value types can not be passed around efficiently. Does C#7 offer a way to create named tuples of the Tuple type?

2条回答
一纸荒年 Trace。
2楼-- · 2019-04-30 01:48

If you mean if there's a way to attach other names to the properties of System.Tuple<...> instances, no there isn't.

Depending on why you want it, you might get around it by converting System.Tuple<...> instances to System.ValueTuple<...> instances using the ToValueTuple overloads in TupleExtensions and back using the ToTuple overloads.

If you don't really need the tuples, you can deconstruct them into discrete variables using the Deconstruct overloads or the var (v1, .., vn) = tuple deconstruction syntax.

查看更多
趁早两清
3楼-- · 2019-04-30 02:00

Not sure what the problem is; everything works as expected for me for passing the new ValueTuple<T> with out, ref, and the new ref locals.

I'm using .NET 4.7 and have my C#7 compiler set to "latest" in the .csproj settings "Advanced..." button.

Demonstration functions:

static (int, int) g = (1, 2);

static void SetValues(int a, int b, ref (int, int) tt) => tt = (a, b);

static void SetValuesOut(int a, int b, out (int, int) tt) => tt = (a, b);

static ref (int, int) GetKnownTuple() => ref g;

static ref (int, int) SelectRef(
    int ix, 
    ref (int, int) x, 
    ref (int, int) y, 
    ref (int, int) z)
{
    if (ix == 0) return ref x;
    if (ix == 1) return ref y;
    return ref z;
}

Usage Examples:

/// use 'ref return' to initialize a new 'ref local' tuple 'aa'
ref (int, int) aa = ref GetKnownTuple();

/// or use the same function without 'ref' to create a local COPY 'bb'
var bb = GetKnownTuple();

/// use 'ref' parameter to modify values of local copy 'bb' ('aa/g' are not altered)
SetValues(3, 4, ref bb);

/// deconstruction of 'ref local' tuple; reads values from referent 'g' (1, 2)
(int x, int y) = aa;

/// 'ref local' reference to a local tuple copy
ref (int, int) dd = ref bb;

/// use 'out' parameter to construct a new (non-'ref') local tuple 'cc'
SetValuesOut(y, x, out (int, int) cc);

/// ...or use 'out' with 'ref local' to wholly replace existing referent ('g' here)
SetValuesOut(5, 6, out aa);

/// 'ref return' function can also be used as assignment l-value...
GetKnownTuple() = (7, 8);

/// ('aa/g' are altered; locals 'bb' and 'cc' remain unchanged)

/// ...or assign a referent via 'ref local' variable (changes 'g' again)
aa = (9, 10);

/// conditional assignment via 'ref return'  (changes 'g' again)
SelectRef(0, ref aa, ref bb, ref cc) = (11, 12);

It should be clear that much more is possible, but all cannot be shown here since the OP's question does not get into too many specific further requirements.

查看更多
登录 后发表回答