static private ExpressionTypeDoesNotMatchAssignment ( object p0, object p1 ) : |
||
p0 | object | |
p1 | object | |
return |
public static UsingCSharpStatement Using(ParameterExpression variable, Expression resource, Expression body) { RequiresCanRead(resource, nameof(resource)); RequiresCanRead(body, nameof(body)); var resourceType = resource.Type; if (variable != null) { var variableType = variable.Type; ValidateType(variableType); ValidateType(resourceType); // NB: No non-null value to nullable value assignment allowed here. This is consistent with Assign, // and the C# compiler should insert the Convert node. if (!AreReferenceAssignable(variableType, resourceType)) { throw LinqError.ExpressionTypeDoesNotMatchAssignment(resourceType, variableType); } } var resourceTypeNonNull = resourceType.GetNonNullableType(); // NB: We don't handle implicit conversions here; the C# compiler can emit a Convert node, // just like it does for those type of conversions in various other places. if (!typeof(IDisposable).IsAssignableFrom(resourceTypeNonNull)) { throw LinqError.ExpressionTypeDoesNotMatchAssignment(resourceTypeNonNull, typeof(IDisposable)); } return(new UsingCSharpStatement(variable, resource, body)); }
/// <summary> /// Reduces the pattern by applying it the specified object. /// </summary> /// <param name="object">The object to match the pattern against.</param> /// <returns>The expression representing the pattern applied to the specified object.</returns> internal override Expression Reduce(Expression @object) { if (!AreReferenceAssignable(InputType, @object.Type)) { throw LinqError.ExpressionTypeDoesNotMatchAssignment(@object.Type, InputType); } // NB: RecursiveCSharpPattern has a peephole optimization for the pattern below. // NB: Ensure any side-effects in evaluating @object are retained. return(PatternHelpers.Reduce(@object, _ => ConstantTrue)); }
/// <summary> /// Creates a <see cref="LocalDeclaration"/> that represents a local declaration. /// </summary> /// <param name="variable">The variable that is being declared.</param> /// <param name="expression">The initializer expression representing the value to assign to the variable.</param> /// <returns>The created <see cref="LocalDeclaration"/>.</returns> public static LocalDeclaration LocalDeclaration(ParameterExpression variable, Expression expression) { RequiresNotNull(variable, nameof(variable)); RequiresCanRead(expression, nameof(expression)); // NB: No non-null value to nullable value assignment allowed here. This is consistent with Assign, // and the C# compiler should insert the Convert node. if (!AreReferenceAssignable(variable.Type, expression.Type)) { throw LinqError.ExpressionTypeDoesNotMatchAssignment(expression.Type, variable.Type); } return(new LocalDeclaration(variable, expression)); }
public static UsingCSharpStatement Using(ParameterExpression variable, Expression resource, Expression body) { var resourceType = resource.Type; if (variable != null) { var variableType = variable.Type; // NB: No non-null value to nullable value assignment allowed here. This is consistent with Assign, // and the C# compiler should insert the Convert node. if (!AreReferenceAssignable(variableType, resourceType)) { throw LinqError.ExpressionTypeDoesNotMatchAssignment(resourceType, variableType); } } return(new UsingCSharpStatement(variable, resource, body)); }
internal static void CheckUsingResourceType(Type resourceType, AwaitInfo awaitInfo, LambdaExpression patternDispose, bool allowConvertToDisposable = false) { ValidateType(resourceType); var resourceTypeNonNull = resourceType.GetNonNullableType(); Type disposeReturnType; if (patternDispose != null) { var patternDisposeInputType = patternDispose.Parameters[0].Type; if (!AreReferenceAssignable(patternDisposeInputType, resourceTypeNonNull)) { throw Error.UsingPatternDisposeInputNotCompatibleWithResource(patternDisposeInputType, resourceTypeNonNull); } disposeReturnType = patternDispose.ReturnType; } else { Type disposableInterface; if (awaitInfo != null) { disposableInterface = typeof(IAsyncDisposable); disposeReturnType = typeof(ValueTask); } else { disposableInterface = typeof(IDisposable); disposeReturnType = typeof(void); } if (allowConvertToDisposable) { // NB: In the case of foreach, we allow for a conversion to a disposable interface to be emitted. // While this conversion or type check can sometimes be elided at runtime, we call the factory // here for its side-effect of doing the neccessary checks. _ = Expression.Convert(Expression.Variable(resourceType), disposableInterface); } else { // NB: We don't handle implicit conversions here; the C# compiler can emit a Convert node, // just like it does for those type of conversions in various other places. if (!disposableInterface.IsAssignableFrom(resourceTypeNonNull)) { throw LinqError.ExpressionTypeDoesNotMatchAssignment(resourceTypeNonNull, disposableInterface); } } } if (awaitInfo != null) { awaitInfo.RequiresCanBind(Expression.Parameter(disposeReturnType)); } else { if (disposeReturnType != typeof(void)) { throw Error.UsingDisposeShouldReturnVoid(); } } }