本文整理汇总了C#中BinaryOperatorKind.Unlifted方法的典型用法代码示例。如果您正苦于以下问题:C# BinaryOperatorKind.Unlifted方法的具体用法?C# BinaryOperatorKind.Unlifted怎么用?C# BinaryOperatorKind.Unlifted使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BinaryOperatorKind
的用法示例。
在下文中一共展示了BinaryOperatorKind.Unlifted方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: TrivialLiftedComparisonOperatorOptimizations
private BoundExpression TrivialLiftedComparisonOperatorOptimizations(
CSharpSyntaxNode syntax,
BinaryOperatorKind kind,
BoundExpression left,
BoundExpression right,
MethodSymbol method)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
// Optimization #1: if both sides are null then the result
// is either true (for equality) or false (for everything else.)
bool leftAlwaysNull = NullableNeverHasValue(left);
bool rightAlwaysNull = NullableNeverHasValue(right);
TypeSymbol boolType = _compilation.GetSpecialType(SpecialType.System_Boolean);
if (leftAlwaysNull && rightAlwaysNull)
{
return MakeLiteral(syntax, ConstantValue.Create(kind.Operator() == BinaryOperatorKind.Equal), boolType);
}
// Optimization #2: If both sides are non-null then we can again eliminate the lifting entirely.
BoundExpression leftNonNull = NullableAlwaysHasValue(left);
BoundExpression rightNonNull = NullableAlwaysHasValue(right);
if (leftNonNull != null && rightNonNull != null)
{
return MakeBinaryOperator(
syntax: syntax,
operatorKind: kind.Unlifted(),
loweredLeft: leftNonNull,
loweredRight: rightNonNull,
type: boolType,
method: method);
}
// Optimization #3: If one side is null and the other is definitely not, then we generate the side effects
// of the non-null side and result in true (for not-equals) or false (for everything else.)
BinaryOperatorKind operatorKind = kind.Operator();
if (leftAlwaysNull && rightNonNull != null || rightAlwaysNull && leftNonNull != null)
{
BoundExpression result = MakeLiteral(syntax, ConstantValue.Create(operatorKind == BinaryOperatorKind.NotEqual), boolType);
BoundExpression nonNull = leftAlwaysNull ? rightNonNull : leftNonNull;
if (ReadIsSideeffecting(nonNull))
{
result = new BoundSequence(
syntax: syntax,
locals: ImmutableArray<LocalSymbol>.Empty,
sideEffects: ImmutableArray.Create<BoundExpression>(nonNull),
value: result,
type: boolType);
}
return result;
}
// Optimization #4: If one side is null and the other is unknown, then we have three cases:
// #4a: If we have x == null then that becomes !x.HasValue.
// #4b: If we have x != null then that becomes x.HasValue.
// #4c: If we have x OP null then that becomes side effects of x, result in false.
if (leftAlwaysNull || rightAlwaysNull)
{
BoundExpression maybeNull = leftAlwaysNull ? right : left;
if (operatorKind == BinaryOperatorKind.Equal || operatorKind == BinaryOperatorKind.NotEqual)
{
BoundExpression callHasValue = MakeNullableHasValue(syntax, maybeNull);
BoundExpression result = operatorKind == BinaryOperatorKind.Equal ?
MakeUnaryOperator(UnaryOperatorKind.BoolLogicalNegation, syntax, null, callHasValue, boolType) :
callHasValue;
return result;
}
else
{
BoundExpression falseExpr = MakeBooleanConstant(syntax, operatorKind == BinaryOperatorKind.NotEqual);
return _factory.Sequence(maybeNull, falseExpr);
}
}
return null;
}
示例2: LowerLiftedUserDefinedComparisonOperator
//.........这里部分代码省略.........
// result = tempX.HasValue & tempY.HasValue ?
// tempX.GetValueOrDefault() OP tempY.GetValueOrDefault() :
// false;
//
// We have not yet optimized the case where we have a known-not-null value on one side,
// and an unknown value on the other. In those cases we will still generate a temp, but
// we will not generate the call to the unnecessary nullable ctor or to GetValueOrDefault.
// Rather, we will generate the value's temp instead of a call to GetValueOrDefault, and generate
// literal true for HasValue. The tree construction methods we call will use those constants
// to eliminate unnecessary branches.
BoundExpression xNonNull = NullableAlwaysHasValue(loweredLeft);
BoundExpression yNonNull = NullableAlwaysHasValue(loweredRight);
// TODO: (This TODO applies throughout this file, not just to this method.)
// TODO: We might be storing a constant to this temporary that we could simply inline.
// TODO: (There are other expressions that can be safely moved around other than constants
// TODO: as well -- for example a boxing conversion of a constant int to object.)
// TODO: Build a better temporary-storage management system that decides whether or not
// TODO: to store a temporary.
BoundAssignmentOperator tempAssignmentX;
BoundLocal boundTempX = _factory.StoreToTemp(xNonNull ?? loweredLeft, out tempAssignmentX);
BoundAssignmentOperator tempAssignmentY;
BoundLocal boundTempY = _factory.StoreToTemp(yNonNull ?? loweredRight, out tempAssignmentY);
BoundExpression callX_GetValueOrDefault = MakeOptimizedGetValueOrDefault(syntax, boundTempX);
BoundExpression callY_GetValueOrDefault = MakeOptimizedGetValueOrDefault(syntax, boundTempY);
BoundExpression callX_HasValue = MakeOptimizedHasValue(syntax, boundTempX);
BoundExpression callY_HasValue = MakeOptimizedHasValue(syntax, boundTempY);
// tempx.HasValue == tempy.HasValue
BinaryOperatorKind conditionOperator;
BinaryOperatorKind operatorKind = kind.Operator();
switch (operatorKind)
{
case BinaryOperatorKind.Equal:
case BinaryOperatorKind.NotEqual:
conditionOperator = BinaryOperatorKind.BoolEqual;
break;
default:
conditionOperator = BinaryOperatorKind.BoolAnd;
break;
}
TypeSymbol boolType = _compilation.GetSpecialType(SpecialType.System_Boolean);
BoundExpression condition = MakeBinaryOperator(
syntax: syntax,
operatorKind: conditionOperator,
loweredLeft: callX_HasValue,
loweredRight: callY_HasValue,
type: boolType,
method: null);
// tempX.GetValueOrDefault() OP tempY.GetValueOrDefault()
BoundExpression unliftedOp = MakeBinaryOperator(
syntax: syntax,
operatorKind: kind.Unlifted(),
loweredLeft: callX_GetValueOrDefault,
loweredRight: callY_GetValueOrDefault,
type: boolType,
method: method);
BoundExpression consequence;
if (operatorKind == BinaryOperatorKind.Equal || operatorKind == BinaryOperatorKind.NotEqual)
{
// tempx.HasValue ? tempX.GetValueOrDefault() == tempY.GetValueOrDefault() : true
consequence = RewriteConditionalOperator(
syntax: syntax,
rewrittenCondition: callX_HasValue,
rewrittenConsequence: unliftedOp,
rewrittenAlternative: MakeLiteral(syntax, ConstantValue.Create(operatorKind == BinaryOperatorKind.Equal), boolType),
constantValueOpt: null,
rewrittenType: boolType);
}
else
{
// tempX.GetValueOrDefault() OP tempY.GetValueOrDefault()
consequence = unliftedOp;
}
// false
BoundExpression alternative = MakeBooleanConstant(syntax, operatorKind == BinaryOperatorKind.NotEqual);
BoundExpression conditionalExpression = RewriteConditionalOperator(
syntax: syntax,
rewrittenCondition: condition,
rewrittenConsequence: consequence,
rewrittenAlternative: alternative,
constantValueOpt: null,
rewrittenType: boolType);
return new BoundSequence(
syntax: syntax,
locals: ImmutableArray.Create<LocalSymbol>(boundTempX.LocalSymbol, boundTempY.LocalSymbol),
sideEffects: ImmutableArray.Create<BoundExpression>(tempAssignmentX, tempAssignmentY),
value: conditionalExpression,
type: boolType);
}
示例3: MakeLiftedBinaryOperatorConsequence
private BoundExpression MakeLiftedBinaryOperatorConsequence(
CSharpSyntaxNode syntax,
BinaryOperatorKind kind,
BoundExpression left,
BoundExpression right,
TypeSymbol type,
MethodSymbol method)
{
// tempX.GetValueOrDefault() OP tempY.GetValueOrDefault()
BoundExpression unliftedOp = MakeBinaryOperator(
syntax: syntax,
operatorKind: kind.Unlifted(),
loweredLeft: left,
loweredRight: right,
type: type.GetNullableUnderlyingType(),
method: method);
// new R?(tempX.GetValueOrDefault() OP tempY.GetValueOrDefault)
return new BoundObjectCreationExpression(
syntax,
GetNullableMethod(syntax, type, SpecialMember.System_Nullable_T__ctor),
unliftedOp);
}