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));
}