本文整理汇总了C#中ReadOnlyArray.RefKinds方法的典型用法代码示例。如果您正苦于以下问题:C# ReadOnlyArray.RefKinds方法的具体用法?C# ReadOnlyArray.RefKinds怎么用?C# ReadOnlyArray.RefKinds使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ReadOnlyArray
的用法示例。
在下文中一共展示了ReadOnlyArray.RefKinds方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: RewriteArguments
/// <summary>
/// Rewrites arguments of an invocation according to the receiving method. It is assumed
/// that arguments match parameters, but may need to be expanded/reordered.
/// </summary>
private void RewriteArguments(
MethodSymbol method,
bool expanded,
ReadOnlyArray<int> argsToParamsOpt,
ref ReadOnlyArray<RefKind> argumentRefKinds,
ref ReadOnlyArray<BoundExpression> rewrittenArguments,
out ReadOnlyArray<LocalSymbol> temporaries)
{
// We have:
// * a list of arguments, already converted to their proper types,
// in source code order. Some optional arguments might be missing.
// * a map showing which parameter each argument corresponds to. If
// this is null, then the argument to parameter mapping is one-to-one.
// * the ref kind of each argument, in source code order. That is, whether
// the argument was marked as ref, out, or value (neither).
// * a method symbol.
// * whether the call is expanded or normal form.
// We rewrite the call so that:
// * if in its expanded form, we create the params array.
// * if the call requires reordering of arguments because of named arguments, temporaries are generated as needed
// Doing this transformation can move around refness in interesting ways. For example, consider
//
// A().M(y : ref B()[C()], x : out D());
//
// This will be created as a call with receiver A(), symbol M, argument list ( B()[C()], D() ),
// name list ( y, x ) and ref list ( ref, out ). We can rewrite this into temporaries:
//
// A().M(
// seq ( ref int temp_y = ref B()[C()], out D() ),
// temp_y );
//
// Now we have a call with receiver A(), symbol M, argument list as shown, no name list,
// and ref list ( out, value ). We do not want to pass a *ref* to temp_y; the temporary
// storage is not the thing being ref'd! We want to pass the *value* of temp_y, which
// *contains* a reference.
// We attempt to minimize the number of temporaries required. Arguments which neither
// produce nor observe a side effect can be placed into their proper position without
// recourse to a temporary. For example:
//
// Where(predicate: x=>x.Length!=0, sequence: S())
//
// can be rewritten without any temporaries because the conversion from lambda to
// delegate does not produce any side effect that could be observed by S().
//
// By contrast:
//
// Foo(z: this.p, y: this.Q(), x: (object)10)
//
// The boxing of 10 can be reordered, but the fetch of this.p has to happen before the
// call to this.Q() because the call could change the value of this.p.
//
// We start by binding everything that is not obviously reorderable as a temporary, and
// then run an optimizer to remove unnecessary temporaries.
ReadOnlyArray<ParameterSymbol> parameters = method.Parameters;
var parameterCount = parameters.Count;
var arguments = new BoundExpression[parameterCount];
temporaries = ReadOnlyArray<LocalSymbol>.Null; // not using temps by default.
List<RefKind> refKinds = null;
if (argumentRefKinds.IsNotNull)
{
refKinds = new List<RefKind>(parameterCount);
for (int p = 0; p < parameterCount; ++p)
{
refKinds.Add(RefKind.None);
}
}
ArrayBuilder<BoundAssignmentOperator> storesToTemps = null;
ArrayBuilder<BoundExpression> paramArray = null;
if (expanded)
{
paramArray = ArrayBuilder<BoundExpression>.GetInstance();
}
for (int a = 0; a < rewrittenArguments.Count; ++a)
{
var argument = rewrittenArguments[a];
var p = (argsToParamsOpt.IsNotNull) ? argsToParamsOpt[a] : a;
var refKind = argumentRefKinds.RefKinds(a);
Debug.Assert(arguments[p] == null);
if (expanded && p == parameterCount - 1)
{
paramArray.Add(argument);
Debug.Assert(refKind == RefKind.None);
}
else if (IsSafeForReordering(argument, refKind))
{
arguments[p] = argument;
if (refKinds != null)
//.........这里部分代码省略.........