diff --git a/src/libraries/Common/src/System/Collections/Generic/LargeArrayBuilder.cs b/src/libraries/Common/src/System/Collections/Generic/LargeArrayBuilder.cs index bf28fb607b239b..3c06e37e9ee607 100644 --- a/src/libraries/Common/src/System/Collections/Generic/LargeArrayBuilder.cs +++ b/src/libraries/Common/src/System/Collections/Generic/LargeArrayBuilder.cs @@ -6,7 +6,7 @@ namespace System.Collections.Generic { /// - /// Represents a position within a . + /// Represents a position within a . /// [DebuggerDisplay("{DebuggerDisplay,nq}")] internal readonly struct CopyPosition @@ -26,7 +26,7 @@ internal CopyPosition(int row, int column) } /// - /// Represents a position at the start of a . + /// Represents a position at the start of a . /// public static CopyPosition Start => default(CopyPosition); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs index bccac308a0133d..6f8072c8f54e6a 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs @@ -11,9 +11,57 @@ namespace System.Linq.Expressions { - /// - /// Represents an expression that has a binary operator. - /// + /// Represents an expression that has a binary operator. + /// The following tables summarize the factory methods that can be used to create a that has a specific node type, represented by the property. Each table contains information for a specific class of operations such as arithmetic or bitwise. + /// ## Binary Arithmetic Operations + /// |Node Type|Factory Method| + /// |---------------|--------------------| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ## Bitwise Operations + /// |Node Type|Factory Method| + /// |---------------|--------------------| + /// ||| + /// ||| + /// ||| + /// ## Shift Operations + /// |Node Type|Factory Method| + /// |---------------|--------------------| + /// ||| + /// ||| + /// ## Conditional Boolean Operations + /// |Node Type|Factory Method| + /// |---------------|--------------------| + /// ||| + /// ||| + /// ## Comparison Operations + /// |Node Type|Factory Method| + /// |---------------|--------------------| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ## Coalescing Operations + /// |Node Type|Factory Method| + /// |---------------|--------------------| + /// ||| + /// ## Array Indexing Operations + /// |Node Type|Factory Method| + /// |---------------|--------------------| + /// ||| + /// In addition, the methods can also be used to create a . These factory methods can be used to create a of any node type that represents a binary operation. The parameter of these methods that is of type specifies the desired node type. + /// The following example creates a object that represents the subtraction of one number from another. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet8"::: [DebuggerTypeProxy(typeof(BinaryExpressionProxy))] public class BinaryExpression : Expression { @@ -23,9 +71,8 @@ internal BinaryExpression(Expression left, Expression right) Right = right; } - /// - /// Gets a value that indicates whether the expression tree node can be reduced. - /// + /// Gets a value that indicates whether the expression tree node can be reduced. + /// if the expression tree node can be reduced; otherwise, . public override bool CanReduce { get @@ -58,37 +105,30 @@ private static bool IsOpAssignment(ExpressionType op) return false; } - /// - /// Gets the right operand of the binary operation. - /// + /// Gets the right operand of the binary operation. + /// An that represents the right operand of the binary operation. public Expression Right { get; } - /// - /// Gets the left operand of the binary operation. - /// + /// Gets the left operand of the binary operation. + /// An that represents the left operand of the binary operation. public Expression Left { get; } - /// - /// Gets the implementing method for the binary operation. - /// + /// Gets the implementing method for the binary operation. + /// The that represents the implementing method. + /// If a represents an operation that uses a predefined operator, the property is . public MethodInfo? Method => GetMethod(); internal virtual MethodInfo? GetMethod() => null; + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. // Note: takes children in evaluation order, which is also the order // that ExpressionVisitor visits them. Having them this way reduces the // chances people will make a mistake and use an inconsistent order in // derived visitors. - - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. public BinaryExpression Update(Expression left, LambdaExpression? conversion, Expression right) { if (left == Left && right == Right && conversion == Conversion) @@ -109,13 +149,10 @@ public BinaryExpression Update(Expression left, LambdaExpression? conversion, Ex return Expression.MakeBinary(NodeType, left, right, IsLiftedToNull, Method, conversion); } - /// - /// Reduces the binary expression node to a simpler expression. - /// If CanReduce returns true, this should return a valid expression. - /// This method is allowed to return another node which itself - /// must be reduced. - /// + /// Reduces the binary expression node to a simpler expression. /// The reduced expression. + /// If CanReduce returns true, this should return a valid expression. + /// This method can return another node which itself must be reduced. public override Expression Reduce() { // Only reduce OpAssignment expressions. @@ -269,16 +306,16 @@ private Expression ReduceIndex() return Expression.Block(vars.ToReadOnly(), exprs.ToReadOnly()); } - /// - /// Gets the type conversion function that is used by a coalescing or compound assignment operation. - /// + /// Gets the type conversion function that is used by a coalescing or compound assignment operation. + /// A that represents a type conversion function. + /// The property is for any whose property is not . public LambdaExpression? Conversion => GetConversion(); internal virtual LambdaExpression? GetConversion() => null; - /// - /// Gets a value that indicates whether the expression tree node represents a lifted call to an operator. - /// + /// Gets a value that indicates whether the expression tree node represents a *lifted* call to an operator. + /// if the node represents a lifted call; otherwise, . + /// An operator call is lifted if the operator expects non-nullable operands but nullable operands are passed to it. public bool IsLifted { get @@ -297,14 +334,15 @@ public bool IsLifted } } - /// - /// Gets a value that indicates whether the expression tree node represents a lifted call to an operator whose return type is lifted to a nullable type. - /// + /// Gets a value that indicates whether the expression tree node represents a *lifted* call to an operator whose return type is lifted to a nullable type. + /// if the operator's return type is lifted to a nullable type; otherwise, . + /// An operator call is lifted if the operator expects non-nullable operands but nullable operands are passed to it. If the value of is , the operator returns a nullable type, and if a nullable operand evaluates to , the operator returns . public bool IsLiftedToNull => IsLifted && Type.IsNullableType(); - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitBinary(this); @@ -570,18 +608,22 @@ internal MethodBinaryExpression(ExpressionType nodeType, Expression left, Expres internal override MethodInfo GetMethod() => _method; } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { #region Assign - - /// - /// Creates a that represents an assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. - /// + /// Creates a that represents an assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// The `Assign` expression copies a value for value types, and it copies a reference for reference types. + /// The following code example shows how to create an expression that represents an assignment operation. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet12"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet12"::: public static BinaryExpression Assign(Expression left, Expression right) { RequiresCanWrite(left, nameof(left)); @@ -856,43 +898,48 @@ private static bool IsValidLiftedConditionalLogicalOperator(Type left, Type righ TypeUtils.AreEquivalent(pms[1].ParameterType, right.GetNonNullableType()); } - /// - /// Creates a , given the left and right operands, by calling an appropriate factory method. - /// - /// The ExpressionType that specifies the type of binary operation. - /// An Expression that represents the left operand. - /// An Expression that represents the right operand. - /// The BinaryExpression that results from calling the appropriate factory method. + /// Creates a , given the left and right operands, by calling an appropriate factory method. + /// The that specifies the type of binary operation. + /// An that represents the left operand. + /// An that represents the right operand. + /// The that results from calling the appropriate factory method. + /// does not correspond to a binary expression node. + /// or is . + /// The parameter determines which factory method this method calls. For example, if is , this method invokes . + /// The following example demonstrates how to use the method to create a that represents the subtraction of one number from another. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet8"::: public static BinaryExpression MakeBinary(ExpressionType binaryType, Expression left, Expression right) { return MakeBinary(binaryType, left, right, liftToNull: false, method: null, conversion: null); } - /// - /// Creates a , given the left and right operands, by calling an appropriate factory method. - /// - /// The ExpressionType that specifies the type of binary operation. - /// An Expression that represents the left operand. - /// An Expression that represents the right operand. - /// true to set IsLiftedToNull to true; false to set IsLiftedToNull to false. - /// A MethodInfo that specifies the implementing method. - /// The BinaryExpression that results from calling the appropriate factory method. + /// Creates a , given the left operand, right operand and implementing method, by calling the appropriate factory method. + /// The that specifies the type of binary operation. + /// An that represents the left operand. + /// An that represents the right operand. + /// to set to ; to set to . + /// A that specifies the implementing method. + /// The that results from calling the appropriate factory method. + /// does not correspond to a binary expression node. + /// or is . + /// The parameter determines which factory method this method will call. For example, if is , this method invokes . The and parameters are ignored if the appropriate factory method does not have a corresponding parameter. public static BinaryExpression MakeBinary(ExpressionType binaryType, Expression left, Expression right, bool liftToNull, MethodInfo? method) { return MakeBinary(binaryType, left, right, liftToNull, method, conversion: null); } - /// - /// - /// Creates a , given the left and right operands, by calling an appropriate factory method. - /// - /// The ExpressionType that specifies the type of binary operation. - /// An Expression that represents the left operand. - /// An Expression that represents the right operand. - /// true to set IsLiftedToNull to true; false to set IsLiftedToNull to false. - /// A MethodInfo that specifies the implementing method. - /// A LambdaExpression that represents a type conversion function. This parameter is used if binaryType is Coalesce or compound assignment. - /// The BinaryExpression that results from calling the appropriate factory method. + /// Creates a , given the left operand, right operand, implementing method and type conversion function, by calling the appropriate factory method. + /// The that specifies the type of binary operation. + /// An that represents the left operand. + /// An that represents the right operand. + /// to set to ; to set to . + /// A that specifies the implementing method. + /// A that represents a type conversion function. This parameter is used only if is or compound assignment. + /// The that results from calling the appropriate factory method. + /// does not correspond to a binary expression node. + /// or is . + /// The parameter determines which factory method this method will call. For example, if is , this method invokes . The , and parameters are ignored if the appropriate factory method does not have a corresponding parameter. public static BinaryExpression MakeBinary(ExpressionType binaryType, Expression left, Expression right, bool liftToNull, MethodInfo? method, LambdaExpression? conversion) => binaryType switch { @@ -940,28 +987,58 @@ public static BinaryExpression MakeBinary(ExpressionType binaryType, Expression #region Equality Operators - /// - /// Creates a that represents an equality comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an equality comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The equality operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is . Otherwise, it is . The property is always . The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the equality operator, the that represents that method is the implementing method. + /// - Otherwise, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is . + /// The following code example shows how to create an expression that checks whether the values of its two arguments are equal. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet8"::: public static BinaryExpression Equal(Expression left, Expression right) { return Equal(left, right, liftToNull: false, method: null); } - /// - /// Creates a that represents an equality comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// true to set IsLiftedToNull to true; false to set IsLiftedToNull to false. - /// A that has the property equal to - /// and the , , , and properties set to the specified values. - /// + /// Creates a that represents an equality comparison. The implementing method can be specified. + /// An to set the property equal to. + /// An to set the property equal to. + /// to set to ; to set to . + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the equality operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is and the property is equal to . Otherwise, they are both . The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the equality operator, the that represents that method is the implementing method. + /// - Otherwise, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted; also, the type of the node is nullable if is or if is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is nullable if is or if is . public static BinaryExpression Equal(Expression left, Expression right, bool liftToNull, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -973,14 +1050,10 @@ public static BinaryExpression Equal(Expression left, Expression right, bool lif return GetMethodBasedBinaryOperator(ExpressionType.Equal, left, right, method, liftToNull); } - /// - /// Creates a that represents a reference equality comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. - /// + /// Creates a that represents a reference equality comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression ReferenceEqual(Expression left, Expression right) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -992,28 +1065,57 @@ public static BinaryExpression ReferenceEqual(Expression left, Expression right) throw Error.ReferenceEqualityNotDefined(left.Type, right.Type); } - /// - /// Creates a that represents an inequality comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an inequality comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The inequality operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is . Otherwise, it is . The property is always . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the inequality operator, the that represents that method is the implementing method. + /// - Otherwise, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is . public static BinaryExpression NotEqual(Expression left, Expression right) { return NotEqual(left, right, liftToNull: false, method: null); } - /// - /// Creates a that represents an inequality comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// true to set IsLiftedToNull to true; false to set IsLiftedToNull to false. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , and properties set to the specified values. - /// + /// Creates a that represents an inequality comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// to set to ; to set to . + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the inequality operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is and the property is equal to . Otherwise, they are both . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the inequality operator, the that represents that method is the implementing method. + /// - Otherwise, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted; also, the type of the node is nullable if is or if is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is nullable if is or if is . public static BinaryExpression NotEqual(Expression left, Expression right, bool liftToNull, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1025,14 +1127,10 @@ public static BinaryExpression NotEqual(Expression left, Expression right, bool return GetMethodBasedBinaryOperator(ExpressionType.NotEqual, left, right, method, liftToNull); } - /// - /// Creates a that represents a reference inequality comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. - /// + /// Creates a that represents a reference inequality comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression ReferenceNotEqual(Expression left, Expression right) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1081,32 +1179,60 @@ private static BinaryExpression GetEqualityComparisonOperator(ExpressionType bin throw Error.BinaryOperatorNotDefined(binaryType, left.Type, right.Type); } - #endregion - - #region Comparison Expressions - - /// - /// Creates a that represents a "greater than" numeric comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a "greater than" numeric comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The "greater than" operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is . Otherwise, it is . The property is always . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the "greater than" operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is . + /// The following code example shows how to create an expression that compares two integers. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet10"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet10"::: public static BinaryExpression GreaterThan(Expression left, Expression right) { return GreaterThan(left, right, liftToNull: false, method: null); } - /// - /// Creates a that represents a "greater than" numeric comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// true to set IsLiftedToNull to true; false to set IsLiftedToNull to false. - /// A that has the property equal to - /// and the , , , and properties set to the specified values. - /// + /// Creates a that represents a "greater than" numeric comparison. The implementing method can be specified. + /// An to set the property equal to. + /// An to set the property equal to. + /// to set to ; to set to . + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the "greater than" operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is and the property is equal to . Otherwise, they are both . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation : + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the "greater than" operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted; also, the type of the node is nullable if is or if is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is nullable if is or if is . public static BinaryExpression GreaterThan(Expression left, Expression right, bool liftToNull, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1118,29 +1244,60 @@ public static BinaryExpression GreaterThan(Expression left, Expression right, bo return GetMethodBasedBinaryOperator(ExpressionType.GreaterThan, left, right, method, liftToNull); } - /// - /// Creates a that represents a "less than" numeric comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. - + /// Creates a that represents a "less than" numeric comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The "less than" operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is . Otherwise, it is . The property is always . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The implementing method for the operation is chosen based on the following rules: + /// - If the property of either or represents a user-defined type that overloads the "less than" operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is . + /// The following code example shows how to create an expression that compares two integers. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet25"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet25"::: public static BinaryExpression LessThan(Expression left, Expression right) { return LessThan(left, right, liftToNull: false, method: null); } - /// - /// Creates a that represents a "less than" numeric comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// true to set IsLiftedToNull to true; false to set IsLiftedToNull to false. - /// A that has the property equal to - /// and the , , , and properties set to the specified values. - /// + /// Creates a that represents a "less than" numeric comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// to set to ; to set to . + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the "less than" operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is and the property is equal to . Otherwise, they are both . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the "less than" operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted; also, the type of the node is nullable if is or if is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is nullable if is or if is . public static BinaryExpression LessThan(Expression left, Expression right, bool liftToNull, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1152,28 +1309,60 @@ public static BinaryExpression LessThan(Expression left, Expression right, bool return GetMethodBasedBinaryOperator(ExpressionType.LessThan, left, right, method, liftToNull); } - /// - /// Creates a that represents a "greater than or equal" numeric comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a "greater than or equal" numeric comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The "greater than or equal" operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is . Otherwise, it is . The property is always . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the "greater than or equal" operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is . + /// The following code example shows how to create an expression that compares two integers. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet11"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet11"::: public static BinaryExpression GreaterThanOrEqual(Expression left, Expression right) { return GreaterThanOrEqual(left, right, liftToNull: false, method: null); } - /// - /// Creates a that represents a "greater than or equal" numeric comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// true to set IsLiftedToNull to true; false to set IsLiftedToNull to false. - /// A that has the property equal to - /// and the , , , and properties set to the specified values. - /// + /// Creates a that represents a "greater than or equal" numeric comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// to set to ; to set to . + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the "greater than or equal" operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is and the property is equal to . Otherwise, they are both . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the "greater than or equal" operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted; also, the type of the node is nullable if is or if is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is nullable if is or if is . public static BinaryExpression GreaterThanOrEqual(Expression left, Expression right, bool liftToNull, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1185,28 +1374,60 @@ public static BinaryExpression GreaterThanOrEqual(Expression left, Expression ri return GetMethodBasedBinaryOperator(ExpressionType.GreaterThanOrEqual, left, right, method, liftToNull); } - /// - /// Creates a that represents a "less than or equal" numeric comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a " less than or equal" numeric comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The "less than or equal" operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is . Otherwise, it is . The property is always . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the "less than or equal" operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is . + /// The following code example shows how to create an expression that compares two integers. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet26"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet26"::: public static BinaryExpression LessThanOrEqual(Expression left, Expression right) { return LessThanOrEqual(left, right, liftToNull: false, method: null); } - /// - /// Creates a that represents a "less than or equal" numeric comparison. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// true to set IsLiftedToNull to true; false to set IsLiftedToNull to false. - /// A that has the property equal to - /// and the , , , and properties set to the specified values. - /// + /// Creates a that represents a "less than or equal" numeric comparison. + /// An to set the property equal to. + /// An to set the property equal to. + /// to set to ; to set to . + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the "less than or equal" operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the property is and the property is equal to . Otherwise, they are both . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the "less than or equal" operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted; also, the type of the node is nullable if is or if is : + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is . + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is . + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is nullable if is or if is . public static BinaryExpression LessThanOrEqual(Expression left, Expression right, bool liftToNull, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1234,31 +1455,73 @@ private static BinaryExpression GetComparisonOperator(ExpressionType binaryType, return GetUserDefinedBinaryOperatorOrThrow(binaryType, opName, left, right, liftToNull); } - #endregion - - #region Boolean Expressions - - /// - /// Creates a that represents a conditional AND operation that evaluates the second operand only if it has to. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a conditional operation that evaluates the second operand only if the first operand evaluates to . + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The bitwise operator is not defined for .Type and .Type. + /// -or- + /// .Type and .Type are not the same Boolean type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the bitwise `AND` operator, the that represents that method is the implementing method. + /// [!NOTE] + /// > The conditional `AND` operator cannot be overloaded in C# or Visual Basic. However, the conditional `AND` operator is evaluated by using the bitwise `AND` operator. Thus, a user-defined overload of the bitwise `AND` operator can be the implementing method for this node type. + /// ]]> + /// - Otherwise, if .Type and .Type are Boolean types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable, and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - .Type and .Type are the same Boolean type. + /// - If .Type and .Type are non-nullable, the node is not lifted. The type of the node is the result type of the predefined conditional `AND` operator. + /// - If .Type and .Type are nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined conditional `AND` operator. + /// The following code example shows how to create an expression that performs a logical AND operation on its two operands only if the first operand evaluates to . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet19"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet19"::: public static BinaryExpression AndAlso(Expression left, Expression right) { return AndAlso(left, right, method: null); } - /// - /// Creates a that represents a conditional AND operation that evaluates the second operand only if it has to. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a conditional operation that evaluates the second operand only if the first operand is resolved to true. The implementing method can be specified. + /// A to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the bitwise operator is not defined for .Type and .Type. + /// -or- + /// is and .Type and .Type are not the same Boolean type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The implementing method for the operation is chosen based on the following rules: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the bitwise `AND` operator, the that represents that method is the implementing method. + /// [!NOTE] + /// > The conditional `AND` operator cannot be overloaded in C# or Visual Basic. However, the conditional `AND` operator is evaluated by using the bitwise `AND` operator. Thus, a user-defined overload of the bitwise `AND` operator can be the implementing method for this node type. + /// ]]> + /// - Otherwise, if .Type and .Type are Boolean types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable, and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - .Type and .Type are the same Boolean type. + /// - If .Type and .Type are non-nullable, the node is not lifted. The type of the node is the result type of the predefined conditional `AND` operator. + /// - If .Type and .Type are nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined conditional `AND` operator. public static BinaryExpression AndAlso(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1291,27 +1554,73 @@ public static BinaryExpression AndAlso(Expression left, Expression right, Method return new MethodBinaryExpression(ExpressionType.AndAlso, left, right, returnType, method); } - /// - /// Creates a that represents a conditional OR operation that evaluates the second operand only if it has to. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a conditional operation that evaluates the second operand only if the first operand evaluates to . + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The bitwise operator is not defined for .Type and .Type. + /// -or- + /// .Type and .Type are not the same Boolean type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the bitwise `OR` operator, the that represents that method is the implementing method. + /// [!NOTE] + /// > The conditional `OR` operator cannot be overloaded in C# or Visual Basic. However, the conditional `OR` operator is evaluated by using the bitwise `OR` operator. Thus, a user-defined overload of the bitwise `OR` operator can be the implementing method for this node type. + /// ]]> + /// - Otherwise, if .Type and .Type are Boolean types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable, and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - .Type and .Type are the same Boolean type. + /// - If .Type and .Type are non-nullable, the node is not lifted. The type of the node is the result type of the predefined conditional `OR` operator. + /// - If .Type and .Type are nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined conditional `OR` operator. + /// The following code example shows how to create an expression that represents a logical `OR` operation that evaluates the second operand only if the first operand evaluates to . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet29"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet29"::: public static BinaryExpression OrElse(Expression left, Expression right) { return OrElse(left, right, method: null); } - /// - /// Creates a that represents a conditional OR operation that evaluates the second operand only if it has to. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a conditional operation that evaluates the second operand only if the first operand evaluates to . + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the bitwise operator is not defined for .Type and .Type. + /// -or- + /// is and .Type and .Type are not the same Boolean type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the bitwise `OR` operator, the that represents that method is the implementing method. + /// [!NOTE] + /// > The conditional `OR` operator cannot be overloaded in C# or Visual Basic. However, the conditional `OR` operator is evaluated by using the bitwise `OR` operator. Thus, a user-defined overload of the bitwise `OR` operator can be the implementing method for this node type. + /// ]]> + /// - Otherwise, if .Type and .Type are Boolean types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable, and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - .Type and .Type are the same Boolean type. + /// - If .Type and .Type are non-nullable, the node is not lifted. The type of the node is the result type of the predefined conditional `OR` operator. + /// - If .Type and .Type are nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined conditional `OR` operator. public static BinaryExpression OrElse(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1344,31 +1653,45 @@ public static BinaryExpression OrElse(Expression left, Expression right, MethodI return new MethodBinaryExpression(ExpressionType.OrElse, left, right, returnType, method); } - #endregion - - #region Coalescing Expressions - - /// - /// Creates a that represents a coalescing operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a coalescing operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The property of does not represent a reference type or a nullable value type. + /// .Type and .Type are not convertible to each other. + /// The property of the resulting is and both and are set to . The property is equal to the result type of the coalescing operation. The property is . + /// #### Result Type + /// The following rules determine the result type: + /// - If .Type represents a nullable type and .Type is implicitly convertible to the corresponding non-nullable type, the result type is the non-nullable equivalent of .Type. + /// - Otherwise, if .Type is implicitly convertible to .Type, the result type is .Type. + /// - Otherwise, if the non-nullable equivalent of .Type is implicitly convertible to .Type, the result type is .Type. + /// ?? Operator (C# Reference) public static BinaryExpression Coalesce(Expression left, Expression right) { return Coalesce(left, right, conversion: null); } - /// - /// Creates a that represents a coalescing operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A LambdaExpression to set the Conversion property equal to. - /// A that has the property equal to - /// and the , and properties set to the specified values. - /// + /// Creates a that represents a coalescing operation, given a conversion function. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , and properties set to the specified values. + /// or is . + /// .Type and .Type are not convertible to each other. + /// -or- + /// is not and .Type is a delegate type that does not take exactly one argument. + /// The property of does not represent a reference type or a nullable value type. + /// -or- + /// The property of represents a type that is not assignable to the parameter type of the delegate type .Type. + /// -or- + /// The property of is not equal to the return type of the delegate type .Type. + /// The property of the resulting is and both and are set to . + /// The property of the resulting is equal to the result type of the coalescing operation. + /// The following rules determine the result type: + /// - If .Type represents a nullable type and .Type is implicitly convertible to the corresponding non-nullable type, the result type is the non-nullable equivalent of .Type. + /// - Otherwise, if .Type is implicitly convertible to .Type, the result type is .Type. + /// - Otherwise, if the non-nullable equivalent of .Type is implicitly convertible to .Type, the result type is .Type. public static BinaryExpression Coalesce(Expression left, Expression right, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1441,31 +1764,59 @@ private static Type ValidateCoalesceArgTypes(Type left, Type right) } } - #endregion - - #region Arithmetic Expressions - - /// - /// Creates a that represents an arithmetic addition operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an arithmetic addition operation that does not have overflow checking. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The addition operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the selected implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the addition operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined addition operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined addition operator. + /// The following code example shows how to create an expression that adds two integers. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet1"::: public static BinaryExpression Add(Expression left, Expression right) { return Add(left, right, method: null); } - /// - /// Creates a that represents an arithmetic addition operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents an arithmetic addition operation that does not have overflow checking. The implementing method can be specified. + /// A to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the addition operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the addition operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined addition operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined addition operator. public static BinaryExpression Add(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1481,43 +1832,35 @@ public static BinaryExpression Add(Expression left, Expression right, MethodInfo return GetMethodBasedBinaryOperator(ExpressionType.Add, left, right, method, liftToNull: true); } - /// - /// Creates a that represents an addition assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an addition assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// + /// The following code example shows how to create an expression that adds a value to an integer variable and then assigns the result of the operation to the variable. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet18"::: public static BinaryExpression AddAssign(Expression left, Expression right) { return AddAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents an addition assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents an addition assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression AddAssign(Expression left, Expression right, MethodInfo? method) { return AddAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents an addition assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents an addition assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression AddAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1562,45 +1905,31 @@ private static void ValidateOpAssignConversionLambda(LambdaExpression conversion } } - /// - /// Creates a that represents an addition assignment operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and - /// properties set to the specified values. - /// + /// Creates a that represents an addition assignment operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression AddAssignChecked(Expression left, Expression right) { return AddAssignChecked(left, right, method: null); } - /// - /// Creates a that represents an addition assignment operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents an addition assignment operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression AddAssignChecked(Expression left, Expression right, MethodInfo? method) { return AddAssignChecked(left, right, method, conversion: null); } - /// - /// Creates a that represents an addition assignment operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents an addition assignment operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression AddAssignChecked(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1623,27 +1952,56 @@ public static BinaryExpression AddAssignChecked(Expression left, Expression righ return GetMethodBasedAssignOperator(ExpressionType.AddAssignChecked, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents an arithmetic addition operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an arithmetic addition operation that has overflow checking. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The addition operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the addition operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined addition operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined addition operator. public static BinaryExpression AddChecked(Expression left, Expression right) { return AddChecked(left, right, method: null); } - /// - /// Creates a that represents an arithmetic addition operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents an arithmetic addition operation that has overflow checking. The implementing method can be specified. + /// A to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the addition operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The implementing method for the operation is chosen based on the following rules: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the addition operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined addition operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined addition operator. public static BinaryExpression AddChecked(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1659,27 +2017,59 @@ public static BinaryExpression AddChecked(Expression left, Expression right, Met return GetMethodBasedBinaryOperator(ExpressionType.AddChecked, left, right, method, liftToNull: true); } - /// - /// Creates a that represents an arithmetic subtraction operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an arithmetic subtraction operation that does not have overflow checking. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The subtraction operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the selected implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the subtraction operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined subtraction operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined subtraction operator. + /// The following code example shows how to create an expression that subtracts the argument from the first argument. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet30"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet30"::: public static BinaryExpression Subtract(Expression left, Expression right) { return Subtract(left, right, method: null); } - /// - /// Creates a that represents an arithmetic subtraction operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents an arithmetic subtraction operation that does not have overflow checking. + /// A to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the subtraction operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the subtraction operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined subtraction operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined subtraction operator. public static BinaryExpression Subtract(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1695,43 +2085,31 @@ public static BinaryExpression Subtract(Expression left, Expression right, Metho return GetMethodBasedBinaryOperator(ExpressionType.Subtract, left, right, method, liftToNull: true); } - /// - /// Creates a that represents a subtraction assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a subtraction assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression SubtractAssign(Expression left, Expression right) { return SubtractAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents a subtraction assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a subtraction assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression SubtractAssign(Expression left, Expression right, MethodInfo? method) { return SubtractAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents a subtraction assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a subtraction assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression SubtractAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1753,43 +2131,31 @@ public static BinaryExpression SubtractAssign(Expression left, Expression right, return GetMethodBasedAssignOperator(ExpressionType.SubtractAssign, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents a subtraction assignment operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a subtraction assignment operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression SubtractAssignChecked(Expression left, Expression right) { return SubtractAssignChecked(left, right, method: null); } - /// - /// Creates a that represents a subtraction assignment operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a subtraction assignment operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression SubtractAssignChecked(Expression left, Expression right, MethodInfo? method) { return SubtractAssignChecked(left, right, method, conversion: null); } - /// - /// Creates a that represents a subtraction assignment operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a subtraction assignment operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression SubtractAssignChecked(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1811,27 +2177,56 @@ public static BinaryExpression SubtractAssignChecked(Expression left, Expression return GetMethodBasedAssignOperator(ExpressionType.SubtractAssignChecked, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents an arithmetic subtraction operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an arithmetic subtraction operation that has overflow checking. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The subtraction operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the selected implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the subtraction operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined subtraction operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined subtraction operator. public static BinaryExpression SubtractChecked(Expression left, Expression right) { return SubtractChecked(left, right, method: null); } - /// - /// Creates a that represents an arithmetic subtraction operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents an arithmetic subtraction operation that has overflow checking. + /// A to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the subtraction operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation : + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the subtraction operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined subtraction operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined subtraction operator. public static BinaryExpression SubtractChecked(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1847,27 +2242,59 @@ public static BinaryExpression SubtractChecked(Expression left, Expression right return GetMethodBasedBinaryOperator(ExpressionType.SubtractChecked, left, right, method, liftToNull: true); } - /// - /// Creates a that represents an arithmetic division operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an arithmetic division operation. + /// An to set the property to. + /// An to set the property to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The division operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the division operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined division operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined division operator. + /// The following code example shows how to create an expression that divides its first argument by its second argument. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet7"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet7"::: public static BinaryExpression Divide(Expression left, Expression right) { return Divide(left, right, method: null); } - /// - /// Creates a that represents an arithmetic division operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents an arithmetic division operation. The implementing method can be specified. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the division operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the division operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined division operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined division operator. public static BinaryExpression Divide(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1883,43 +2310,31 @@ public static BinaryExpression Divide(Expression left, Expression right, MethodI return GetMethodBasedBinaryOperator(ExpressionType.Divide, left, right, method, liftToNull: true); } - /// - /// Creates a that represents a division assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a division assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression DivideAssign(Expression left, Expression right) { return DivideAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents a division assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a division assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression DivideAssign(Expression left, Expression right, MethodInfo? method) { return DivideAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents a division assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a division assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression DivideAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1941,27 +2356,56 @@ public static BinaryExpression DivideAssign(Expression left, Expression right, M return GetMethodBasedAssignOperator(ExpressionType.DivideAssign, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents an arithmetic remainder operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an arithmetic remainder operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The modulus operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the selected implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the modulus operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined modulus operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined modulus operator. public static BinaryExpression Modulo(Expression left, Expression right) { return Modulo(left, right, method: null); } - /// - /// Creates a that represents an arithmetic remainder operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents an arithmetic remainder operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the modulus operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The implementing method for the operation is chosen based on the following rules: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the modulus operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined modulus operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined modulus operator. public static BinaryExpression Modulo(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -1977,43 +2421,31 @@ public static BinaryExpression Modulo(Expression left, Expression right, MethodI return GetMethodBasedBinaryOperator(ExpressionType.Modulo, left, right, method, liftToNull: true); } - /// - /// Creates a that represents a remainder assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a remainder assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression ModuloAssign(Expression left, Expression right) { return ModuloAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents a remainder assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a remainder assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression ModuloAssign(Expression left, Expression right, MethodInfo? method) { return ModuloAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents a remainder assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a remainder assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression ModuloAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2035,27 +2467,59 @@ public static BinaryExpression ModuloAssign(Expression left, Expression right, M return GetMethodBasedAssignOperator(ExpressionType.ModuloAssign, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents an arithmetic multiplication operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an arithmetic multiplication operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The multiplication operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the selected implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the multiplication operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined multiplication operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined multiplication operator. + /// The following code example shows how to create an expression that multiplies two values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet27"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet27"::: public static BinaryExpression Multiply(Expression left, Expression right) { return Multiply(left, right, method: null); } - /// - /// Creates a that represents an arithmetic multiplication operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents an arithmetic multiplication operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the multiplication operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the multiplication operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined multiplication operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined multiplication operator. public static BinaryExpression Multiply(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2071,43 +2535,31 @@ public static BinaryExpression Multiply(Expression left, Expression right, Metho return GetMethodBasedBinaryOperator(ExpressionType.Multiply, left, right, method, liftToNull: true); } - /// - /// Creates a that represents a multiplication assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a multiplication assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression MultiplyAssign(Expression left, Expression right) { return MultiplyAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents a multiplication assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a multiplication assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression MultiplyAssign(Expression left, Expression right, MethodInfo? method) { return MultiplyAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents a multiplication assignment operation that does not have overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a multiplication assignment operation that does not have overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression MultiplyAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2129,43 +2581,31 @@ public static BinaryExpression MultiplyAssign(Expression left, Expression right, return GetMethodBasedAssignOperator(ExpressionType.MultiplyAssign, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents a multiplication assignment operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a multiplication assignment operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression MultiplyAssignChecked(Expression left, Expression right) { return MultiplyAssignChecked(left, right, method: null); } - /// - /// Creates a that represents a multiplication assignment operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a multiplication assignment operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression MultiplyAssignChecked(Expression left, Expression right, MethodInfo? method) { return MultiplyAssignChecked(left, right, method, conversion: null); } - /// - /// Creates a that represents a multiplication assignment operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a multiplication assignment operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression MultiplyAssignChecked(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2187,27 +2627,56 @@ public static BinaryExpression MultiplyAssignChecked(Expression left, Expression return GetMethodBasedAssignOperator(ExpressionType.MultiplyAssignChecked, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents an arithmetic multiplication operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents an arithmetic multiplication operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The multiplication operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the selected implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the multiplication operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined multiplication operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined multiplication operator. public static BinaryExpression MultiplyChecked(Expression left, Expression right) { return MultiplyChecked(left, right, method: null); } - /// - /// Creates a that represents an arithmetic multiplication operation that has overflow checking. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents an arithmetic multiplication operation that has overflow checking. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the multiplication operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the multiplication operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are numeric types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined multiplication operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined multiplication operator. public static BinaryExpression MultiplyChecked(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2239,27 +2708,56 @@ private static Type GetResultTypeOfShift(Type left, Type right) return left; } - /// - /// Creates a that represents an bitwise left-shift operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a bitwise left-shift operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The left-shift operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the selected implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the left-shift operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type is an integral type (one of , , , , , , , , or the corresponding nullable types) and .Type is , the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined left-shift operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined left-shift operator. public static BinaryExpression LeftShift(Expression left, Expression right) { return LeftShift(left, right, method: null); } - /// - /// Creates a that represents an bitwise left-shift operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a bitwise left-shift operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the left-shift operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the selected implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the left-shift operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type is an integral type (one of , , , , , , , , or the corresponding nullable types) and .Type is , the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined left-shift operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined left-shift operator. public static BinaryExpression LeftShift(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2276,43 +2774,31 @@ public static BinaryExpression LeftShift(Expression left, Expression right, Meth return GetMethodBasedBinaryOperator(ExpressionType.LeftShift, left, right, method, liftToNull: true); } - /// - /// Creates a that represents a bitwise left-shift assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a bitwise left-shift assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression LeftShiftAssign(Expression left, Expression right) { return LeftShiftAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents a bitwise left-shift assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a bitwise left-shift assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression LeftShiftAssign(Expression left, Expression right, MethodInfo? method) { return LeftShiftAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents a bitwise left-shift assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a bitwise left-shift assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression LeftShiftAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2335,27 +2821,56 @@ public static BinaryExpression LeftShiftAssign(Expression left, Expression right return GetMethodBasedAssignOperator(ExpressionType.LeftShiftAssign, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents an bitwise right-shift operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a bitwise right-shift operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The right-shift operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the selected implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the right-shift operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type is an integral type (one of , , , , , , , , or the corresponding nullable types) and .Type is , the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined right-shift operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined right-shift operator. public static BinaryExpression RightShift(Expression left, Expression right) { return RightShift(left, right, method: null); } - /// - /// Creates a that represents an bitwise right-shift operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a bitwise right-shift operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the right-shift operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the selected implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the right-shift operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type is an integral type (one of , , , , , , , , or the corresponding nullable types) and .Type is , the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined right-shift operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined right-shift operator. public static BinaryExpression RightShift(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2372,43 +2887,31 @@ public static BinaryExpression RightShift(Expression left, Expression right, Met return GetMethodBasedBinaryOperator(ExpressionType.RightShift, left, right, method, liftToNull: true); } - /// - /// Creates a that represents a bitwise right-shift assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a bitwise right-shift assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression RightShiftAssign(Expression left, Expression right) { return RightShiftAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents a bitwise right-shift assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a bitwise right-shift assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression RightShiftAssign(Expression left, Expression right, MethodInfo? method) { return RightShiftAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents a bitwise right-shift assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a bitwise right-shift assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression RightShiftAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2431,27 +2934,59 @@ public static BinaryExpression RightShiftAssign(Expression left, Expression righ return GetMethodBasedAssignOperator(ExpressionType.RightShiftAssign, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents an bitwise AND operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a bitwise operation. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The bitwise operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the bitwise `AND` operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are integral or Boolean types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined bitwise `AND` operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined bitwise `AND` operator. + /// The following code example shows how to create an expression that represents a logical AND operation on two Boolean values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet2"::: public static BinaryExpression And(Expression left, Expression right) { return And(left, right, method: null); } - /// - /// Creates a that represents an bitwise AND operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a bitwise operation. The implementing method can be specified. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the bitwise operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The implementing method for the operation is chosen based on the following rules: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method for the node. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the bitwise `AND` operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are integral or Boolean types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined bitwise `AND` operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined bitwise `AND` operator. public static BinaryExpression And(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2467,43 +3002,31 @@ public static BinaryExpression And(Expression left, Expression right, MethodInfo return GetMethodBasedBinaryOperator(ExpressionType.And, left, right, method, liftToNull: true); } - /// - /// Creates a that represents a bitwise AND assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a bitwise AND assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression AndAssign(Expression left, Expression right) { return AndAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents a bitwise AND assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a bitwise AND assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression AndAssign(Expression left, Expression right, MethodInfo? method) { return AndAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents a bitwise AND assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a bitwise AND assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression AndAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2525,27 +3048,59 @@ public static BinaryExpression AndAssign(Expression left, Expression right, Meth return GetMethodBasedAssignOperator(ExpressionType.AndAssign, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents an bitwise OR operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a bitwise operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The bitwise operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the bitwise `OR` operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are integral or Boolean types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined bitwise `OR` operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined bitwise `OR` operator. + /// The following code example shows how to create an expression that represents a logical OR operation. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet28"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet28"::: public static BinaryExpression Or(Expression left, Expression right) { return Or(left, right, method: null); } - /// - /// Creates a that represents an bitwise OR operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a bitwise operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the bitwise operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the bitwise `OR` operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are integral or Boolean types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined bitwise `OR` operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined bitwise `OR` operator. public static BinaryExpression Or(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2561,43 +3116,31 @@ public static BinaryExpression Or(Expression left, Expression right, MethodInfo? return GetMethodBasedBinaryOperator(ExpressionType.Or, left, right, method, liftToNull: true); } - /// - /// Creates a that represents a bitwise OR assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a bitwise OR assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression OrAssign(Expression left, Expression right) { return OrAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents a bitwise OR assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a bitwise OR assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression OrAssign(Expression left, Expression right, MethodInfo? method) { return OrAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents a bitwise OR assignment operation. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a bitwise OR assignment operation. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression OrAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2619,27 +3162,59 @@ public static BinaryExpression OrAssign(Expression left, Expression right, Metho return GetMethodBasedAssignOperator(ExpressionType.OrAssign, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents a bitwise or logical XOR operation, using op_ExclusiveOr for user-defined types. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a bitwise operation, using op_ExclusiveOr for user-defined types. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the `XOR` operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are integral or Boolean types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined `XOR` operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined `XOR` operator. + /// The following code example shows how to create an expression that represents the logical XOR operation. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet9"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet9"::: public static BinaryExpression ExclusiveOr(Expression left, Expression right) { return ExclusiveOr(left, right, method: null); } - /// - /// Creates a that represents a bitwise or logical XOR operation, using op_ExclusiveOr for user-defined types. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a bitwise operation, using op_ExclusiveOr for user-defined types. The implementing method can be specified. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the operator is not defined for .Type and .Type. + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the chosen implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the `XOR` operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are integral or Boolean types, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is : + /// - If .Type and .Type are both non-nullable, the node is not lifted. The type of the node is the result type of the predefined `XOR` operator. + /// - If .Type and .Type are both nullable, the node is lifted. The type of the node is the nullable type that corresponds to the result type of the predefined `XOR` operator. public static BinaryExpression ExclusiveOr(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2655,43 +3230,31 @@ public static BinaryExpression ExclusiveOr(Expression left, Expression right, Me return GetMethodBasedBinaryOperator(ExpressionType.ExclusiveOr, left, right, method, liftToNull: true); } - /// - /// Creates a that represents a bitwise or logical XOR assignment operation, using op_ExclusiveOr for user-defined types. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents a bitwise XOR assignment operation, using op_ExclusiveOr for user-defined types. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression ExclusiveOrAssign(Expression left, Expression right) { return ExclusiveOrAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents a bitwise or logical XOR assignment operation, using op_ExclusiveOr for user-defined types. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents a bitwise XOR assignment operation, using op_ExclusiveOr for user-defined types. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression ExclusiveOrAssign(Expression left, Expression right, MethodInfo? method) { return ExclusiveOrAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents a bitwise or logical XOR assignment operation, using op_ExclusiveOr for user-defined types. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents a bitwise XOR assignment operation, using op_ExclusiveOr for user-defined types. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression ExclusiveOrAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2713,27 +3276,52 @@ public static BinaryExpression ExclusiveOrAssign(Expression left, Expression rig return GetMethodBasedAssignOperator(ExpressionType.ExclusiveOrAssign, left, right, method, conversion, liftToNull: true); } - /// - /// Creates a that represents raising a number to a power. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents raising a number to a power. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The exponentiation operator is not defined for .Type and .Type. + /// -or- + /// .Type and/or .Type are not . + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If the property of either or represents a user-defined type that overloads the exponentiation operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are both , the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. public static BinaryExpression Power(Expression left, Expression right) { return Power(left, right, method: null); } - /// - /// Creates a that represents raising a number to a power. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents raising a number to a power. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly two arguments. + /// is and the exponentiation operator is not defined for .Type and .Type. + /// -or- + /// is and .Type and/or .Type are not . + /// The resulting has the property set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . The property is . + /// The following information describes the implementing method, the node type, and whether a node is lifted. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes two arguments, it is the implementing method. + /// - Otherwise, if the property of either or represents a user-defined type that overloads the exponentiation operator, the that represents that method is the implementing method. + /// - Otherwise, if .Type and .Type are both , the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// - If .Type and .Type are assignable to the corresponding argument types of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type and .Type are both value types of which at least one is nullable and the corresponding non-nullable types are equal to the corresponding argument types of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. public static BinaryExpression Power(Expression left, Expression right, MethodInfo? method) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2771,43 +3359,31 @@ public static BinaryExpression Power(Expression left, Expression right, MethodIn return GetMethodBasedBinaryOperator(ExpressionType.Power, left, right, method, liftToNull: true); } - /// - /// Creates a that represents raising an expression to a power and assigning the result back to the expression. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents raising an expression to a power and assigning the result back to the expression. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. public static BinaryExpression PowerAssign(Expression left, Expression right) { return PowerAssign(left, right, method: null, conversion: null); } - /// - /// Creates a that represents raising an expression to a power and assigning the result back to the expression. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , and properties set to the specified values. - /// + /// Creates a that represents raising an expression to a power and assigning the result back to the expression. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. public static BinaryExpression PowerAssign(Expression left, Expression right, MethodInfo? method) { return PowerAssign(left, right, method, conversion: null); } - /// - /// Creates a that represents raising an expression to a power and assigning the result back to the expression. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , , - /// and properties set to the specified values. - /// + /// Creates a that represents raising an expression to a power and assigning the result back to the expression. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , , and properties set to the specified values. public static BinaryExpression PowerAssign(Expression left, Expression right, MethodInfo? method, LambdaExpression? conversion) { ExpressionUtils.RequiresCanRead(left, nameof(left)); @@ -2824,17 +3400,18 @@ public static BinaryExpression PowerAssign(Expression left, Expression right, Me return GetMethodBasedAssignOperator(ExpressionType.PowerAssign, left, right, method, conversion, liftToNull: true); } - #endregion - - #region ArrayIndex Expression - - /// - /// Creates a that represents applying an array index operator to an array of rank one. - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the and properties set to the specified values. + /// Creates a that represents applying an array index operator to an array of rank one. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// .Type does not represent an array type. + /// -or- + /// .Type represents an array type whose rank is not 1. + /// -or- + /// .Type does not represent the type. + /// must represent an index of type . + /// The property of the resulting is , and both and are set to . The property is equal to the element type of .Type. The property is . public static BinaryExpression ArrayIndex(Expression array, Expression index) { ExpressionUtils.RequiresCanRead(array, nameof(array)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BlockExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BlockExpression.cs index 4d6b22ec6fe734..f177737a6fde13 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BlockExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BlockExpression.cs @@ -10,59 +10,50 @@ namespace System.Linq.Expressions { - /// - /// Represents a block that contains a sequence of expressions where variables can be defined. - /// + /// Represents a block that contains a sequence of expressions where variables can be defined. + /// The methods can be used to create a . + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: [DebuggerTypeProxy(typeof(BlockExpressionProxy))] public class BlockExpression : Expression { - /// - /// Gets the expressions in this block. - /// + /// Gets the expressions in this block. + /// The read-only collection containing all the expressions in this block. public ReadOnlyCollection Expressions => GetOrMakeExpressions(); - /// - /// Gets the variables defined in this block. - /// + /// Gets the variables defined in this block. + /// The read-only collection containing all the variables defined in this block. public ReadOnlyCollection Variables => GetOrMakeVariables(); - /// - /// Gets the last expression in this block. - /// + /// Gets the last expression in this block. + /// The object representing the last expression in this block. public Expression Result => GetExpression(ExpressionCount - 1); internal BlockExpression() { } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitBlock(this); } - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType => ExpressionType.Block; - /// - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public override Type Type => GetExpression(ExpressionCount - 1).Type; - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. /// This expression if no children changed, or an expression with the updated children. public BlockExpression Update(IEnumerable? variables, IEnumerable expressions) { @@ -825,14 +816,18 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() #endregion + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a that contains two expressions and has no variables. - /// + /// Creates a that contains two expressions and has no variables. /// The first expression in the block. /// The second expression in the block. - /// The created . + /// The created . + /// When the block expression is executed, it returns the value of the last expression in the block. public static BlockExpression Block(Expression arg0, Expression arg1) { ExpressionUtils.RequiresCanRead(arg0, nameof(arg0)); @@ -841,13 +836,12 @@ public static BlockExpression Block(Expression arg0, Expression arg1) return new Block2(arg0, arg1); } - /// - /// Creates a that contains three expressions and has no variables. - /// + /// Creates a that contains three expressions and has no variables. /// The first expression in the block. /// The second expression in the block. /// The third expression in the block. - /// The created . + /// The created . + /// When the block expression is executed, it returns the value of the last expression in the block. public static BlockExpression Block(Expression arg0, Expression arg1, Expression arg2) { ExpressionUtils.RequiresCanRead(arg0, nameof(arg0)); @@ -856,14 +850,13 @@ public static BlockExpression Block(Expression arg0, Expression arg1, Expression return new Block3(arg0, arg1, arg2); } - /// - /// Creates a that contains four expressions and has no variables. - /// + /// Creates a that contains four expressions and has no variables. /// The first expression in the block. /// The second expression in the block. /// The third expression in the block. /// The fourth expression in the block. - /// The created . + /// The created . + /// When the block expression is executed, it returns the value of the last expression in the block. public static BlockExpression Block(Expression arg0, Expression arg1, Expression arg2, Expression arg3) { ExpressionUtils.RequiresCanRead(arg0, nameof(arg0)); @@ -873,15 +866,14 @@ public static BlockExpression Block(Expression arg0, Expression arg1, Expression return new Block4(arg0, arg1, arg2, arg3); } - /// - /// Creates a that contains five expressions and has no variables. - /// + /// Creates a that contains five expressions and has no variables. /// The first expression in the block. /// The second expression in the block. /// The third expression in the block. /// The fourth expression in the block. /// The fifth expression in the block. - /// The created . + /// The created . + /// When the block expression is executed, it returns the value of the last expression in the block. public static BlockExpression Block(Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4) { ExpressionUtils.RequiresCanRead(arg0, nameof(arg0)); @@ -893,11 +885,13 @@ public static BlockExpression Block(Expression arg0, Expression arg1, Expression return new Block5(arg0, arg1, arg2, arg3, arg4); } - /// - /// Creates a that contains the given expressions and has no variables. - /// + /// Creates a that contains the given expressions and has no variables. /// The expressions in the block. - /// The created . + /// The created . + /// When the block expression is executed, it returns the value of the last expression in the block. + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public static BlockExpression Block(params Expression[] expressions) { ContractUtils.RequiresNotNull(expressions, nameof(expressions)); @@ -906,68 +900,62 @@ public static BlockExpression Block(params Expression[] expressions) return GetOptimizedBlockExpression(expressions); } - /// - /// Creates a that contains the given expressions and has no variables. - /// + /// Creates a that contains the given expressions and has no variables. /// The expressions in the block. - /// The created . + /// The created . + /// When the block expression is executed, it returns the value of the last expression in the block. public static BlockExpression Block(IEnumerable expressions) { return Block(EmptyReadOnlyCollection.Instance, expressions); } - /// - /// Creates a that contains the given expressions, has no variables and has specific result type. - /// + /// Creates a that contains the given expressions, has no variables and has specific result type. /// The result type of the block. /// The expressions in the block. - /// The created . + /// The created . public static BlockExpression Block(Type type, params Expression[] expressions) { ContractUtils.RequiresNotNull(expressions, nameof(expressions)); return Block(type, (IEnumerable)expressions); } - /// - /// Creates a that contains the given expressions, has no variables and has specific result type. - /// + /// Creates a that contains the given expressions, has no variables and has specific result type. /// The result type of the block. /// The expressions in the block. - /// The created . + /// The created . public static BlockExpression Block(Type type, IEnumerable expressions) { return Block(type, EmptyReadOnlyCollection.Instance, expressions); } - /// - /// Creates a that contains the given variables and expressions. - /// + /// Creates a that contains the given variables and expressions. /// The variables in the block. /// The expressions in the block. - /// The created . + /// The created . + /// When the block expression is executed, it returns the value of the last expression in the block. public static BlockExpression Block(IEnumerable? variables, params Expression[] expressions) { return Block(variables, (IEnumerable)expressions); } - /// - /// Creates a that contains the given variables and expressions. - /// + /// Creates a that contains the given variables and expressions. /// The result type of the block. /// The variables in the block. /// The expressions in the block. - /// The created . + /// The created . public static BlockExpression Block(Type type, IEnumerable? variables, params Expression[] expressions) { return Block(type, variables, (IEnumerable)expressions); } - /// - /// Creates a that contains the given variables and expressions. - /// + /// Creates a that contains the given variables and expressions. /// The variables in the block. /// The expressions in the block. - /// The created . + /// The created . + /// When the block expression is executed, it returns the value of the last expression in the block. + /// The following code example shows how to pass a parameter to a block expression and process this parameter within a block. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet14"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet14"::: public static BlockExpression Block(IEnumerable? variables, IEnumerable expressions) { ContractUtils.RequiresNotNull(expressions, nameof(expressions)); @@ -989,13 +977,11 @@ public static BlockExpression Block(IEnumerable? variables, } } - /// - /// Creates a that contains the given variables and expressions. - /// + /// Creates a that contains the given variables and expressions. /// The result type of the block. /// The variables in the block. /// The expressions in the block. - /// The created . + /// The created . public static BlockExpression Block(Type type, IEnumerable? variables, IEnumerable expressions) { ContractUtils.RequiresNotNull(type, nameof(type)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/CatchBlock.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/CatchBlock.cs index df72abf31836c9..17aeb5367c9a75 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/CatchBlock.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/CatchBlock.cs @@ -6,10 +6,8 @@ namespace System.Linq.Expressions { - /// - /// Represents a catch statement in a try block. - /// This must have the same return type (i.e., the type of ) as the try block it is associated with. - /// + /// Represents a catch statement in a try block. + /// The methods can be used to create a . [DebuggerTypeProxy(typeof(Expression.CatchBlockProxy))] public sealed class CatchBlock { @@ -21,44 +19,34 @@ internal CatchBlock(Type test, ParameterExpression? variable, Expression body, E Filter = filter; } - /// - /// Gets a reference to the object caught by this handler. - /// + /// Gets a reference to the object caught by this handler. + /// The object representing a reference to the object caught by this handler. public ParameterExpression? Variable { get; } - /// - /// Gets the type of this handler catches. - /// + /// Gets the type of this handler catches. + /// The object representing the type of this handler catches. public Type Test { get; } - /// - /// Gets the body of the catch block. - /// + /// Gets the body of the catch block. + /// The object representing the catch body. public Expression Body { get; } - /// - /// Gets the body of the 's filter. - /// + /// Gets the body of the filter. + /// The object representing the body of the filter. public Expression? Filter { get; } - /// - /// Returns a that represents the current . - /// - /// A that represents the current . + /// Returns a that represents the current . + /// A that represents the current . public override string ToString() { return ExpressionStringBuilder.CatchBlockToString(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public CatchBlock Update(ParameterExpression? variable, Expression? filter, Expression body) { if (variable == Variable && filter == Filter && body == Body) @@ -69,69 +57,61 @@ public CatchBlock Update(ParameterExpression? variable, Expression? filter, Expr } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a representing a catch statement. - /// The of object to be caught can be specified but no reference to the object - /// will be available for use in the . - /// - /// The of this will handle. + /// Creates a representing a catch statement. + /// The of this will handle. /// The body of the catch statement. - /// The created . + /// The created . + /// The of to be caught can be specified but no reference to the object will be available for use in the . public static CatchBlock Catch(Type type, Expression body) { return MakeCatchBlock(type, null, body, filter: null); } - /// - /// Creates a representing a catch statement with a reference to the caught object for use in the handler body. - /// - /// A representing a reference to the object caught by this handler. + /// Creates a representing a catch statement with a reference to the caught object for use in the handler body. + /// A representing a reference to the object caught by this handler. /// The body of the catch statement. - /// The created . + /// The created . public static CatchBlock Catch(ParameterExpression variable, Expression body) { ContractUtils.RequiresNotNull(variable, nameof(variable)); return MakeCatchBlock(variable.Type, variable, body, filter: null); } - /// - /// Creates a representing a catch statement with - /// an filter but no reference to the caught object. - /// - /// The of this will handle. + /// Creates a representing a catch statement with an filter but no reference to the caught object. + /// The of this will handle. /// The body of the catch statement. - /// The body of the filter. - /// The created . + /// The body of the filter. + /// The created . public static CatchBlock Catch(Type type, Expression body, Expression? filter) { return MakeCatchBlock(type, null, body, filter); } - /// - /// Creates a representing a catch statement with - /// an filter and a reference to the caught object. - /// - /// A representing a reference to the object caught by this handler. + /// Creates a representing a catch statement with an filter and a reference to the caught object. + /// A representing a reference to the object caught by this handler. /// The body of the catch statement. - /// The body of the filter. - /// The created . + /// The body of the filter. + /// The created . public static CatchBlock Catch(ParameterExpression variable, Expression body, Expression? filter) { ContractUtils.RequiresNotNull(variable, nameof(variable)); return MakeCatchBlock(variable.Type, variable, body, filter); } - /// - /// Creates a representing a catch statement with the specified elements. - /// - /// The of this will handle. - /// A representing a reference to the object caught by this handler. + /// Creates a representing a catch statement with the specified elements. + /// The of this will handle. + /// A representing a reference to the object caught by this handler. /// The body of the catch statement. - /// The body of the filter. - /// The created . - /// must be non-null and match the type of (if it is supplied). + /// The body of the filter. + /// The created . + /// must be non-null and match the type of (if it is supplied). public static CatchBlock MakeCatchBlock(Type type, ParameterExpression? variable, Expression body, Expression? filter) { ContractUtils.RequiresNotNull(type, nameof(type)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ConditionalExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ConditionalExpression.cs index 3be49a5c3347c6..820762a2033c64 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ConditionalExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ConditionalExpression.cs @@ -8,9 +8,12 @@ namespace System.Linq.Expressions { - /// - /// Represents an expression that has a conditional operator. - /// + /// Represents an expression that has a conditional operator. + /// Use the factory method to create a . + /// The of a is . + /// The following code example shows how to create an expression that represents a conditional statement. If the first argument evaluates to , the second argument is executed; otherwise, the third argument is executed. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet3"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet3"::: [DebuggerTypeProxy(typeof(ConditionalExpressionProxy))] public class ConditionalExpression : Expression { @@ -36,32 +39,24 @@ internal static ConditionalExpression Make(Expression test, Expression ifTrue, E } } - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType => ExpressionType.Conditional; - /// - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public override Type Type => IfTrue.Type; - /// - /// Gets the test of the conditional operation. - /// + /// Gets the test of the conditional operation. + /// An that represents the test of the conditional operation. public Expression Test { get; } - /// - /// Gets the expression to execute if the test evaluates to true. - /// + /// Gets the expression to execute if the test evaluates to . + /// An that represents the expression to execute if the test is . public Expression IfTrue { get; } - /// - /// Gets the expression to execute if the test evaluates to false. - /// + /// Gets the expression to execute if the test evaluates to . + /// An that represents the expression to execute if the test is . public Expression IfFalse => GetFalse(); internal virtual Expression GetFalse() @@ -70,22 +65,19 @@ internal virtual Expression GetFalse() return AstUtils.Empty; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitConditional(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// The property of the result. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// The property of the result. /// This expression if no children changed, or an expression with the updated children. public ConditionalExpression Update(Expression test, Expression ifTrue, Expression ifFalse) { @@ -121,17 +113,28 @@ internal FullConditionalExpressionWithType(Expression test, Expression ifTrue, E public sealed override Type Type { get; } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a . - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the , , - /// and properties set to the specified values. + /// Creates a that represents a conditional statement. + /// An to set the property equal to. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or or is . + /// .Type is not . + /// -or- + /// .Type is not equal to .Type. + /// The property of the resulting is equal to the property of . + /// The following code example shows how to create an expression that represents a conditional statement. If the first argument evaluates to , the second argument is executed; otherwise, the third argument is executed. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet3"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet3"::: + /// + /// public static ConditionalExpression Condition(Expression test, Expression ifTrue, Expression ifFalse) { ExpressionUtils.RequiresCanRead(test, nameof(test)); @@ -150,19 +153,13 @@ public static ConditionalExpression Condition(Expression test, Expression ifTrue return ConditionalExpression.Make(test, ifTrue, ifFalse, ifTrue.Type); } - /// - /// Creates a . - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to - /// and the , , - /// and properties set to the specified values. - /// This method allows explicitly unifying the result type of the conditional expression in cases where the types of - /// and expressions are not equal. Types of both and must be implicitly - /// reference assignable to the result type. The is allowed to be . + /// Creates a that represents a conditional statement. + /// An to set the property equal to. + /// An to set the property equal to. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// This method allows explicitly unifying the result type of the conditional expression in cases where the types of and expressions are not equal. Types of both and must be implicitly reference assignable to the result type. The is allowed to be . public static ConditionalExpression Condition(Expression test, Expression ifTrue, Expression ifFalse, Type type) { ExpressionUtils.RequiresCanRead(test, nameof(test)); @@ -187,30 +184,28 @@ public static ConditionalExpression Condition(Expression test, Expression ifTrue return ConditionalExpression.Make(test, ifTrue, ifFalse, type); } - /// - /// Creates a . - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the , , - /// properties set to the specified values. The property is set to default expression and - /// the type of the resulting returned by this method is . + /// Creates a that represents a conditional block with an statement. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the , , properties set to the specified values. The property is set to default expression and the type of the resulting returned by this method is . + /// + /// The following code example shows how to create an expression that represents a conditional block. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet32"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet32"::: public static ConditionalExpression IfThen(Expression test, Expression ifTrue) { return Condition(test, ifTrue, Expression.Empty(), typeof(void)); } - /// - /// Creates a . - /// - /// An to set the property equal to. - /// An to set the property equal to. - /// An to set the property equal to. - /// A that has the property equal to - /// and the , , - /// and properties set to the specified values. The type of the resulting - /// returned by this method is . + /// Creates a that represents a conditional block with and statements. + /// An to set the property equal to. + /// An to set the property equal to. + /// An to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. The type of the resulting returned by this method is . + /// + /// The following code example shows how to create an expression that represents a conditional block. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet33"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet33"::: public static ConditionalExpression IfThenElse(Expression test, Expression ifTrue, Expression ifFalse) { return Condition(test, ifTrue, ifFalse, typeof(void)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ConstantExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ConstantExpression.cs index e4adc598570bdd..5ceb881dacfe14 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ConstantExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ConstantExpression.cs @@ -6,9 +6,12 @@ namespace System.Linq.Expressions { - /// - /// Represents an expression that has a constant value. - /// + /// Represents an expression that has a constant value. + /// Use the factory methods to create a . + /// The of a is . + /// The following code example shows how to create an expression that represents a constant value by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet4"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet4"::: [DebuggerTypeProxy(typeof(ConstantExpressionProxy))] public class ConstantExpression : Expression { @@ -17,10 +20,8 @@ internal ConstantExpression(object? value) Value = value; } - /// - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public override Type Type { get @@ -34,21 +35,18 @@ public override Type Type } } - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this Expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType => ExpressionType.Constant; - /// - /// Gets the value of the constant expression. - /// + /// Gets the value of the constant expression. + /// An equal to the value of the represented expression. public object? Value { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitConstant(this); @@ -66,32 +64,36 @@ internal TypedConstantExpression(object? value, Type type) public sealed override Type Type { get; } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a that has the property set to the specified value. . - /// - /// An to set the property equal to. - /// - /// A that has the property equal to - /// and the property set to the specified value. - /// + /// Creates a that has the property set to the specified value. + /// An to set the property equal to. + /// A that has the property equal to and the property set to the specified value. + /// The property of the resulting is equal to the type of . If is , is equal to . + /// To represent , you can also use the method, with which you can explicitly specify the type. + /// The following code example shows how to create an expression that represents a constant value. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet4"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet4"::: public static ConstantExpression Constant(object? value) { return new ConstantExpression(value); } - /// - /// Creates a that has the - /// and properties set to the specified values. . - /// - /// An to set the property equal to. - /// A to set the property equal to. - /// - /// A that has the property equal to - /// and the and - /// properties set to the specified values. - /// + /// Creates a that has the and properties set to the specified values. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// is not and is not assignable from the dynamic type of . + /// This method can be useful for representing values of nullable types. + /// The following code example shows how to create an expression that represents a constant of the nullable type and set its value to . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet22"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet22"::: public static ConstantExpression Constant(object? value, Type type) { ContractUtils.RequiresNotNull(type, nameof(type)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DebugInfoExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DebugInfoExpression.cs index d27ea67ad5dfd9..afd8120b269a70 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DebugInfoExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DebugInfoExpression.cs @@ -7,12 +7,7 @@ namespace System.Linq.Expressions { - /// - /// Emits or clears a sequence point for debug information. - /// - /// This allows the debugger to highlight the correct source code when - /// debugging. - /// + /// Emits or clears a sequence point for debug information. This allows the debugger to highlight the correct source code when debugging. [DebuggerTypeProxy(typeof(DebugInfoExpressionProxy))] public class DebugInfoExpression : Expression { @@ -21,71 +16,62 @@ internal DebugInfoExpression(SymbolDocumentInfo document) Document = document; } - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type => typeof(void); - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.DebugInfo; - /// - /// Gets the start line of this . - /// + /// Gets the start line of this . + /// The number of the start line of the code that was used to generate the wrapped expression. [ExcludeFromCodeCoverage(Justification = "Unreachable")] public virtual int StartLine { get { throw ContractUtils.Unreachable; } } - /// - /// Gets the start column of this . - /// + /// Gets the start column of this . + /// The number of the start column of the code that was used to generate the wrapped expression. [ExcludeFromCodeCoverage(Justification = "Unreachable")] public virtual int StartColumn { get { throw ContractUtils.Unreachable; } } - /// - /// Gets the end line of this . - /// + /// Gets the end line of this . + /// The number of the end line of the code that was used to generate the wrapped expression. [ExcludeFromCodeCoverage(Justification = "Unreachable")] public virtual int EndLine { get { throw ContractUtils.Unreachable; } } - /// - /// Gets the end column of this . - /// + /// Gets the end column of this . + /// The number of the end column of the code that was used to generate the wrapped expression. [ExcludeFromCodeCoverage(Justification = "Unreachable")] public virtual int EndColumn { get { throw ContractUtils.Unreachable; } } - /// - /// Gets the that represents the source file. - /// + /// Gets the that represents the source file. + /// The that represents the source file. public SymbolDocumentInfo Document { get; } - /// - /// Gets the value to indicate if the is for clearing a sequence point. - /// + /// Gets the value to indicate if the is for clearing a sequence point. + /// if the is for clearing a sequence point; otherwise, . [ExcludeFromCodeCoverage(Justification = "Unreachable")] public virtual bool IsClear { get { throw ContractUtils.Unreachable; } } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitDebugInfo(this); @@ -141,18 +127,20 @@ internal ClearDebugInfoExpression(SymbolDocumentInfo document) public override int EndColumn => 0; } #endregion - + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a with the specified span. - /// - /// The that represents the source file. - /// The start line of this . Must be greater than 0. - /// The start column of this . Must be greater than 0. - /// The end line of this . Must be greater or equal than the start line. - /// The end column of this . If the end line is the same as the start line, it must be greater or equal than the start column. In any case, must be greater than 0. - /// An instance of . + /// Creates a with the specified span. + /// The that represents the source file. + /// The start line of this . Must be greater than 0. + /// The start column of this . Must be greater than 0. + /// The end line of this . Must be greater or equal than the start line. + /// The end column of this . If the end line is the same as the start line, it must be greater or equal than the start column. In any case, must be greater than 0. + /// An instance of . public static DebugInfoExpression DebugInfo(SymbolDocumentInfo document, int startLine, int startColumn, int endLine, int endColumn) { ContractUtils.RequiresNotNull(document, nameof(document)); @@ -165,11 +153,9 @@ public static DebugInfoExpression DebugInfo(SymbolDocumentInfo document, int sta return new SpanDebugInfoExpression(document, startLine, startColumn, endLine, endColumn); } - /// - /// Creates a for clearing a sequence point. - /// - /// The that represents the source file. - /// An instance of for clearing a sequence point. + /// Creates a for clearing a sequence point. + /// The that represents the source file. + /// An instance of for clearing a sequence point. public static DebugInfoExpression ClearDebugInfo(SymbolDocumentInfo document) { ContractUtils.RequiresNotNull(document, nameof(document)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DefaultExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DefaultExpression.cs index 5e951596d8d227..44c84baab5b381 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DefaultExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DefaultExpression.cs @@ -6,9 +6,11 @@ namespace System.Linq.Expressions { - /// - /// Represents the default value of a type or an empty expression. - /// + /// Represents the default value of a type or an empty expression. + /// + /// The following code example shows how to create an expression that represents a default value for a given type by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet6"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet6"::: [DebuggerTypeProxy(typeof(DefaultExpressionProxy))] public sealed class DefaultExpression : Expression { @@ -17,50 +19,48 @@ internal DefaultExpression(Type type) Type = type; } - /// - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type { get; } - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType => ExpressionType.Default; - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitDefault(this); } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates an empty expression that has type. - /// - /// - /// A that has the property equal to - /// and the property set to . - /// + /// Creates an empty expression that has type. + /// A that has the property equal to and the property set to . + /// An empty expression can be used where an expression is expected but no action is desired. For example, you can use an empty expression as the last expression in a block expression. In this case, the block expression's return value is void. + /// The following code example shows how to create an empty expression and add it to a block expression. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet31"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet31"::: public static DefaultExpression Empty() { return new DefaultExpression(typeof(void)); // Create new object each time for different identity } - /// - /// Creates a that has the property set to the specified type. - /// - /// A to set the property equal to. - /// - /// A that has the property equal to - /// and the property set to the specified type. - /// + /// Creates a that has the property set to the specified type. + /// A to set the property equal to. + /// A that has the property equal to and the property set to the specified type. + /// + /// The following code example shows how to create an expression that represents a default value for a given type. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet6"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet6"::: public static DefaultExpression Default(Type type) { ContractUtils.RequiresNotNull(type, nameof(type)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DynamicExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DynamicExpression.cs index 2081496c1b3993..18872c2e0703ac 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DynamicExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DynamicExpression.cs @@ -14,9 +14,7 @@ namespace System.Linq.Expressions { - /// - /// Represents a dynamic operation. - /// + /// Represents a dynamic operation. public class DynamicExpression : Expression, IDynamicExpression { internal DynamicExpression(Type delegateType, CallSiteBinder binder) @@ -108,33 +106,24 @@ internal static DynamicExpression Make(Type returnType, Type delegateType, CallS } } - /// - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public override Type Type => typeof(object); - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType => ExpressionType.Dynamic; - /// - /// Gets the , which determines the runtime behavior of the - /// dynamic site. - /// + /// Gets the , which determines the run-time behavior of the dynamic site. + /// The , which determines the run-time behavior of the dynamic site. public CallSiteBinder Binder { get; } - /// - /// Gets the type of the delegate used by the . - /// + /// Gets the type of the delegate used by the . + /// The object representing the type of the delegate used by the . public Type DelegateType { get; } - /// - /// Gets the arguments to the dynamic operation. - /// + /// Gets the arguments to the dynamic operation. + /// The read-only collections containing the arguments to the dynamic operation. public ReadOnlyCollection Arguments => GetOrMakeArguments(); [ExcludeFromCodeCoverage(Justification = "Unreachable")] @@ -143,9 +132,10 @@ internal virtual ReadOnlyCollection GetOrMakeArguments() throw ContractUtils.Unreachable; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { if (visitor is DynamicExpressionVisitor dynVisitor) @@ -169,13 +159,9 @@ internal virtual DynamicExpression Rewrite(Expression[] args) throw ContractUtils.Unreachable; } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Compares the value sent to the parameter, , to the property of the current instance of . If the values of the parameter and the property are equal, the current instance is returned. If they are not equal, a new instance is returned that is identical to the current instance except that the property is set to the value of parameter . + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public DynamicExpression Update(IEnumerable? arguments) { ICollection? args; @@ -206,274 +192,169 @@ internal virtual bool SameArguments(ICollection? arguments) throw ContractUtils.Unreachable; } - #region IArgumentProvider Members - + /// Returns the argument at index, throwing if index is out of bounds. You should not use this member. It is only public due to assembly refactoring, and it is used internally for performance optimizations. + /// The index of the argument. + /// Returns . [ExcludeFromCodeCoverage(Justification = "Unreachable")] Expression IArgumentProvider.GetArgument(int index) { throw ContractUtils.Unreachable; } + /// Returns the number of arguments to the expression tree node. You should not use this member. It is only public due to assembly refactoring, and it is used internally for performance optimizations. + /// Returns . + /// This member is an explicit interface member implementation. It can be used only when the instance is cast to an interface. [ExcludeFromCodeCoverage(Justification = "Unreachable")] int IArgumentProvider.ArgumentCount { get { throw ContractUtils.Unreachable; } } - #endregion - - #region Members that forward to Expression - - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The arguments to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the result will be inferred - /// from the types of the arguments and the specified return type. - /// + /// A that has equal to , and has the and set to the specified values. + /// The property of the result is inferred from the types of the arguments and the specified return type. public static new DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, params Expression[] arguments) { return ExpressionExtension.Dynamic(binder, returnType, arguments); } - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The arguments to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the result will be inferred - /// from the types of the arguments and the specified return type. - /// + /// A that has equal to , and has the and set to the specified values. + /// The property of the result is inferred from the types of the arguments and the specified return type. public static new DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, IEnumerable arguments) { return ExpressionExtension.Dynamic(binder, returnType, arguments); } - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the result will be inferred - /// from the types of the arguments and the specified return type. - /// + /// A that has equal to , and has the and set to the specified values. + /// The property of the result is inferred from the types of the arguments and the specified return type. public static new DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0) { return ExpressionExtension.Dynamic(binder, returnType, arg0); } - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the result will be inferred - /// from the types of the arguments and the specified return type. - /// + /// A that has equal to , and has the and set to the specified values. + /// The property of the result is inferred from the types of the arguments and the specified return type. public static new DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1) { return ExpressionExtension.Dynamic(binder, returnType, arg0, arg1); } - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the result will be inferred - /// from the types of the arguments and the specified return type. - /// + /// A that has equal to , and has the and set to the specified values. + /// The property of the result is inferred from the types of the arguments and the specified return type. public static new DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1, Expression arg2) { return ExpressionExtension.Dynamic(binder, returnType, arg0, arg1, arg2); } - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. /// The fourth argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the result will be inferred - /// from the types of the arguments and the specified return type. - /// + /// A that has equal to , and has the and set to the specified values. + /// The property of the result is inferred from the types of the arguments and the specified return type. public static new DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1, Expression arg2, Expression arg3) { return ExpressionExtension.Dynamic(binder, returnType, arg0, arg1, arg2, arg3); } - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided . + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The arguments to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to , and has the , , and set to the specified values. public static new DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, IEnumerable? arguments) { return ExpressionExtension.MakeDynamic(delegateType, binder, arguments); } - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided . + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The arguments to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to , and has the , , and set to the specified values. public static new DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, params Expression[]? arguments) { return ExpressionExtension.MakeDynamic(delegateType, binder, arguments); } - /// - /// Creates a that represents a dynamic operation bound by the provided and one argument. - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided and one argument. + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to , and has the , , and set to the specified values. public static new DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0) { return ExpressionExtension.MakeDynamic(delegateType, binder, arg0); } - /// - /// Creates a that represents a dynamic operation bound by the provided and two arguments. - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided and two arguments. + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to , and has the , , and set to the specified values. public static new DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1) { return ExpressionExtension.MakeDynamic(delegateType, binder, arg0, arg1); } - /// - /// Creates a that represents a dynamic operation bound by the provided and three arguments. - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided and three arguments. + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to , and has the , , and set to the specified values. public static new DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2) { return ExpressionExtension.MakeDynamic(delegateType, binder, arg0, arg1, arg2); } - /// - /// Creates a that represents a dynamic operation bound by the provided and four arguments. - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided and four arguments. + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. /// The fourth argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to , and has the , , and set to the specified values. public static new DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2, Expression arg3) { return ExpressionExtension.MakeDynamic(delegateType, binder, arg0, arg1, arg2, arg3); } - #endregion - + /// Rewrite this node replacing the dynamic expression's arguments with the provided values. The number of needs to match the number of the current expression. You should not use this type. It is only public due to assembly refactoring, and it is used internally for performance optimizations. This helper method allows re-writing of nodes to be independent of the specific implementation class deriving from DynamicExpression that is being used at the call site. + /// The arguments. + /// Returns , the rewritten expression. Expression IDynamicExpression.Rewrite(Expression[] args) => Rewrite(args); + /// Optionally creates the CallSite and returns the CallSite for the DynamicExpression's polymorphic inline cache. You should not use this member. It is only public due to assembly refactoring, and it is used internally for performance optimizations. + /// Returns . object IDynamicExpression.CreateCallSite() { return CallSite.Create(this.DelegateType, this.Binder); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DynamicExpressionVisitor.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DynamicExpressionVisitor.cs index 6a509e7fdc9537..e0aca6015ae85e 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DynamicExpressionVisitor.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/DynamicExpressionVisitor.cs @@ -5,14 +5,13 @@ namespace System.Linq.Expressions { + /// Represents a visitor or rewriter for dynamic expression trees. + /// This class is designed to be inherited to create more specialized classes whose functionality requires traversing, examining, or copying a dynamic expression tree. public class DynamicExpressionVisitor : ExpressionVisitor { - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// Returns , the modified expression, if it or any subexpression is modified; otherwise, returns the original expression. protected internal override Expression VisitDynamic(DynamicExpression node) { Expression[]? a = ExpressionVisitorUtils.VisitArguments(this, node); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ElementInit.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ElementInit.cs index 111ab815461dcd..5f133d682257e9 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ElementInit.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ElementInit.cs @@ -8,9 +8,11 @@ namespace System.Linq.Expressions { - /// - /// Represents the initialization of a list. - /// + /// Represents an initializer for a single element of an collection. + /// + /// The following example creates an that represents the initialization of an element of a dictionary collection. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet4"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet4"::: public sealed class ElementInit : IArgumentProvider { internal ElementInit(MethodInfo addMethod, ReadOnlyCollection arguments) @@ -19,14 +21,12 @@ internal ElementInit(MethodInfo addMethod, ReadOnlyCollection argume Arguments = arguments; } - /// - /// Gets the used to add elements to the object. - /// + /// Gets the instance method that is used to add an element to an collection. + /// A that represents an instance method that adds an element to a collection. public MethodInfo AddMethod { get; } - /// - /// Gets the list of elements to be added to the object. - /// + /// Gets the collection of arguments that are passed to a method that adds an element to an collection. + /// A of objects that represent the arguments for a method that adds an element to a collection. public ReadOnlyCollection Arguments { get; } /// @@ -41,22 +41,16 @@ internal ElementInit(MethodInfo addMethod, ReadOnlyCollection argume /// public int ArgumentCount => Arguments.Count; - /// - /// Creates a representation of the node. - /// - /// A representation of the node. + /// Returns a textual representation of an object. + /// A textual representation of the object. public override string ToString() { return ExpressionStringBuilder.ElementInitBindingToString(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public ElementInit Update(IEnumerable arguments) { if (arguments == Arguments) @@ -67,25 +61,58 @@ public ElementInit Update(IEnumerable arguments) } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates an expression that represents the initialization of a list. - /// - /// The for the list's Add method. - /// An array containing the Expressions to be used to initialize the list. - /// The created expression. + /// Creates an , given an array of values as the second argument. + /// A to set the property equal to. + /// An array of objects to set the property equal to. + /// An that has the and properties set to the specified values. + /// or is . + /// The method that addMethod represents is not named "Add" (case insensitive). + /// -or- + /// The method that addMethod represents is not an instance method. + /// -or- + /// arguments does not contain the same number of elements as the number of parameters for the method that addMethod represents. + /// -or- + /// The property of one or more elements of is not assignable to the type of the corresponding parameter of the method that represents. + /// The parameter must represent an instance method named "Add" (case insensitive). The add method must have the same number of parameters as the number of elements in . The property of each element in must be assignable to the type of the corresponding parameter of the add method, possibly after *quoting*. + /// [!NOTE] + /// > An element will be quoted only if the corresponding method parameter is of type . Quoting means the element is wrapped in a node. The resulting node is a whose property is the element of `arguments`. + /// ]]> + /// The following example demonstrates how to use the method to create an that represents calling the method to initialize an element of a dictionary collection. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet4"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet4"::: public static ElementInit ElementInit(MethodInfo addMethod, params Expression[] arguments) { return ElementInit(addMethod, arguments as IEnumerable); } - /// - /// Creates an expression that represents the initialization of a list. - /// - /// The for the list's Add method. - /// An containing elements to initialize the list. - /// The created expression. + /// Creates an , given an as the second argument. + /// A to set the property equal to. + /// An that contains objects to set the property equal to. + /// An that has the and properties set to the specified values. + /// or is . + /// The method that represents is not named "Add" (case insensitive). + /// -or- + /// The method that represents is not an instance method. + /// -or- + /// does not contain the same number of elements as the number of parameters for the method that represents. + /// -or- + /// The property of one or more elements of is not assignable to the type of the corresponding parameter of the method that represents. + /// The parameter must represent an instance method named "Add" (case insensitive). The add method must have the same number of parameters as the number of elements in . The property of each element in must be assignable to the type of the corresponding parameter of the add method, possibly after *quoting*. + /// [!NOTE] + /// > An element will be quoted only if the corresponding method parameter is of type . Quoting means the element is wrapped in a node. The resulting node is a whose property is the element of `arguments`. + /// ]]> + /// The following example demonstrates how to use the method to create an that represents calling the method to initialize an element of a dictionary collection. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet4"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet4"::: public static ElementInit ElementInit(MethodInfo addMethod, IEnumerable arguments) { ContractUtils.RequiresNotNull(addMethod, nameof(addMethod)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Expression.DebuggerProxy.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Expression.DebuggerProxy.cs index 85064e7249a89b..69b9c5a91754a6 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Expression.DebuggerProxy.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Expression.DebuggerProxy.cs @@ -7,6 +7,11 @@ namespace System.Linq.Expressions { + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { internal sealed class BinaryExpressionProxy diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Expression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Expression.cs index d9341dad16b1a8..d0314f2ca5f161 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Expression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Expression.cs @@ -12,9 +12,11 @@ namespace System.Linq.Expressions { - /// - /// The base type for all nodes in Expression Trees. - /// + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public abstract partial class Expression { internal const string ExpressionRequiresUnreferencedCode = "Creating Expressions requires unreferenced code because the members being referenced by the Expression may be trimmed."; @@ -45,11 +47,10 @@ public ExtensionInfo(ExpressionType nodeType, Type type) private static ConditionalWeakTable? s_legacyCtorSupportTable; - /// - /// Constructs a new instance of . - /// - /// The of the . - /// The of the . + /// Initializes a new instance of the class. + /// The to set as the node type. + /// The of this . + /// This constructor is called from constructors in derived classes. [Obsolete("use a different constructor that does not take ExpressionType. Then override NodeType and Type properties to provide the values that would be specified to this constructor.")] protected Expression(ExpressionType nodeType, Type type) { @@ -66,16 +67,15 @@ protected Expression(ExpressionType nodeType, Type type) s_legacyCtorSupportTable.Add(this, new ExtensionInfo(nodeType, type)); } - /// - /// Constructs a new instance of . - /// + /// Constructs a new instance of . protected Expression() { } - /// - /// The of the . - /// + /// Gets the node type of this . + /// One of the values. + /// The property provides a more specialized description of an than just its derived type. For example, a can be used to represent many different kinds of binary expressions, such as a division operation or a "greater than" operation. The property would describe these binary expressions as and , respectively. + /// The static CLR type of the expression that the object represents is represented by the property. public virtual ExpressionType NodeType { get @@ -90,10 +90,11 @@ public virtual ExpressionType NodeType } } - - /// - /// The of the value represented by this . - /// + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. + /// The is the type of the expression tree node, whereas the represents the static common language runtime (CLR) type of the expression that the node represents. For example, two nodes with different node types can have the same , as shown in the following code example. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet36"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet36"::: public virtual Type Type { get @@ -108,17 +109,11 @@ public virtual Type Type } } - /// - /// Indicates that the node can be reduced to a simpler node. If this - /// returns true, Reduce() can be called to produce the reduced form. - /// + /// Indicates that the node can be reduced to a simpler node. If this returns true, Reduce() can be called to produce the reduced form. + /// if the node can be reduced; otherwise, . public virtual bool CanReduce => false; - /// - /// Reduces this node to a simpler expression. If CanReduce returns - /// true, this should return a valid expression. This method is - /// allowed to return another node which itself must be reduced. - /// + /// Reduces this node to a simpler expression. If CanReduce returns true, this should return a valid expression. This method can return another node which itself must be reduced. /// The reduced expression. public virtual Expression Reduce() { @@ -126,53 +121,28 @@ public virtual Expression Reduce() return this; } - /// - /// Reduces the node and then calls the method passing the reduced expression. - /// Throws an exception if the node isn't reducible. - /// - /// An instance of . + /// Reduces the node and then calls the visitor delegate on the reduced expression. The method throws an exception if the node is not reducible. + /// An instance of . /// The expression being visited, or an expression which should replace it in the tree. - /// - /// Override this method to provide logic to walk the node's children. - /// A typical implementation will call visitor.Visit on each of its - /// children, and if any of them change, should return a new copy of - /// itself with the modified children. - /// + /// Override this method to provide logic to walk the node's children. A typical implementation will call visitor.Visit on each of its children, and if any of them change, should return a new copy of itself with the modified children. protected internal virtual Expression VisitChildren(ExpressionVisitor visitor) { if (!CanReduce) throw Error.MustBeReducible(); return visitor.Visit(ReduceAndCheck()); } - /// - /// Dispatches to the specific visit method for this node type. For - /// example, will call into - /// . - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . /// The visitor to visit this node with. /// The result of visiting this node. - /// - /// This default implementation for - /// nodes will call . - /// Override this method to call into a more specific method on a derived - /// visitor class of ExprressionVisitor. However, it should still - /// support unknown visitors by calling VisitExtension. - /// + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal virtual Expression Accept(ExpressionVisitor visitor) { return visitor.VisitExtension(this); } - /// - /// Reduces this node to a simpler expression. If CanReduce returns - /// true, this should return a valid expression. This method is - /// allowed to return another node which itself must be reduced. - /// + /// Reduces this node to a simpler expression. If CanReduce returns true, this should return a valid expression. This method can return another node which itself must be reduced. /// The reduced expression. - /// - /// Unlike Reduce, this method checks that the reduced node satisfies - /// certain invariants. - /// + /// Unlike Reduce, this method checks that the reduced node satisfies certain invariants. public Expression ReduceAndCheck() { if (!CanReduce) throw Error.MustBeReducible(); @@ -186,10 +156,7 @@ public Expression ReduceAndCheck() return newNode; } - /// - /// Reduces the expression to a known node type (i.e. not an Extension node) - /// or simply returns the expression if it is already a known type. - /// + /// Reduces the expression to a known node type (that is not an Extension node) or just returns the expression if it is already a known type. /// The reduced expression. public Expression ReduceExtensions() { @@ -201,10 +168,8 @@ public Expression ReduceExtensions() return node; } - /// - /// Creates a representation of the Expression. - /// - /// A representation of the Expression. + /// Returns a textual representation of the . + /// A textual representation of the . public override string ToString() { return ExpressionStringBuilder.ExpressionToString(this); @@ -280,225 +245,117 @@ private static void RequiresCanWrite(Expression expression, string paramName) throw Error.ExpressionMustBeWriteable(paramName); } - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The arguments to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the - /// result will be inferred from the types of the arguments and the specified return type. - /// + /// A that has equal to and has the and set to the specified values. + /// The property of the result will be inferred from the types of the arguments and the specified return type. public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, IEnumerable arguments) => DynamicExpression.Dynamic(binder, returnType, arguments); - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the - /// result will be inferred from the types of the arguments and the specified return type. - /// + /// A that has equal to and has the and set to the specified values. + /// The property of the result will be inferred from the types of the arguments and the specified return type. public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0) => DynamicExpression.Dynamic(binder, returnType, arg0); - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the - /// result will be inferred from the types of the arguments and the specified return type. - /// + /// A that has equal to and has the and set to the specified values. + /// The property of the result will be inferred from the types of the arguments and the specified return type. public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1) => DynamicExpression.Dynamic(binder, returnType, arg0, arg1); - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the - /// result will be inferred from the types of the arguments and the specified return type. - /// + /// A that has equal to and has the and set to the specified values. + /// The property of the result will be inferred from the types of the arguments and the specified return type. public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1, Expression arg2) => DynamicExpression.Dynamic(binder, returnType, arg0, arg1, arg2); - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. /// The fourth argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the - /// result will be inferred from the types of the arguments and the specified return type. - /// + /// A that has equal to and has the and set to the specified values. + /// The property of the result will be inferred from the types of the arguments and the specified return type. public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1, Expression arg2, Expression arg3) => DynamicExpression.Dynamic(binder, returnType, arg0, arg1, arg2, arg3); - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// + /// Creates a that represents a dynamic operation bound by the provided . /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The arguments to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// Binder and - /// Arguments set to the specified values. - /// - /// - /// The DelegateType property of the - /// result will be inferred from the types of the arguments and the specified return type. - /// + /// A that has equal to and has the and set to the specified values. + /// The property of the result will be inferred from the types of the arguments and the specified return type. public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, params Expression[] arguments) => DynamicExpression.Dynamic(binder, returnType, arguments); - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided . + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The arguments to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to and has the , , and set to the specified values. public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, IEnumerable? arguments) => DynamicExpression.MakeDynamic(delegateType, binder, arguments); - /// - /// Creates a that represents a dynamic operation bound by the provided and one argument. - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided and one argument. + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to and has the , , and set to the specified values. public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0) => DynamicExpression.MakeDynamic(delegateType, binder, arg0); - /// - /// Creates a that represents a dynamic operation bound by the provided and two arguments. - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided and two arguments. + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to and has the , , and set to the specified values. public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1) => DynamicExpression.MakeDynamic(delegateType, binder, arg0, arg1); - /// - /// Creates a that represents a dynamic operation bound by the provided and three arguments. - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided and three arguments. + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to and has the , , and set to the specified values. public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2) => DynamicExpression.MakeDynamic(delegateType, binder, arg0, arg1, arg2); - /// - /// Creates a that represents a dynamic operation bound by the provided and four arguments. - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided and four arguments. + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. /// The fourth argument to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to and has the , , and set to the specified values. public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2, Expression arg3) => DynamicExpression.MakeDynamic(delegateType, binder, arg0, arg1, arg2, arg3); - /// - /// Creates a that represents a dynamic operation bound by the provided . - /// - /// The type of the delegate used by the . + /// Creates a that represents a dynamic operation bound by the provided . + /// The type of the delegate used by the . /// The runtime binder for the dynamic operation. /// The arguments to the dynamic operation. - /// - /// A that has equal to - /// Dynamic and has the - /// DelegateType, - /// Binder, and - /// Arguments set to the specified values. - /// + /// A that has equal to and has the , , and set to the specified values. public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, params Expression[]? arguments) => MakeDynamic(delegateType, binder, (IEnumerable?)arguments); } diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionType.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionType.cs index acaa0ce1ca7a5a..24abd836d94566 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionType.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionType.cs @@ -3,350 +3,179 @@ namespace System.Linq.Expressions { - /// - /// Describes the node types for the nodes of an expression tree. - /// + /// Describes the node types for the nodes of an expression tree. + /// For more information about each enumeration value of this type, see [Dynamic Language Runtime Overview](/dotnet/framework/reflection-and-codedom/dynamic-language-runtime-overview). public enum ExpressionType { - /// - /// A node that represents arithmetic addition without overflow checking. - /// + /// An addition operation, such as a + b, without overflow checking, for numeric operands. Add, - /// - /// A node that represents arithmetic addition with overflow checking. - /// + /// An addition operation, such as (a + b), with overflow checking, for numeric operands. AddChecked, - /// - /// A node that represents a bitwise AND operation. - /// + /// A bitwise or logical operation, such as (a & b) in C# and (a And b) in Visual Basic. And, - /// - /// A node that represents a short-circuiting conditional AND operation. - /// + /// A conditional operation that evaluates the second operand only if the first operand evaluates to . It corresponds to (a && b) in C# and (a AndAlso b) in Visual Basic. AndAlso, - /// - /// A node that represents getting the length of a one-dimensional array. - /// + /// An operation that obtains the length of a one-dimensional array, such as array.Length. ArrayLength, - /// - /// A node that represents indexing into a one-dimensional array. - /// + /// An indexing operation in a one-dimensional array, such as array[index] in C# or array(index) in Visual Basic. ArrayIndex, - /// - /// A node that represents a method call. - /// + /// A method call, such as in the obj.sampleMethod() expression. Call, - /// - /// A node that represents a null coalescing operation. - /// + /// A node that represents a null coalescing operation, such as (a ?? b) in C# or If(a, b) in Visual Basic. Coalesce, - /// - /// A node that represents a conditional operation. - /// + /// A conditional operation, such as a > b ? a : b in C# or If(a > b, a, b) in Visual Basic. Conditional, - /// - /// A node that represents an expression that has a constant value. - /// + /// A constant value. Constant, - /// - /// A node that represents a cast or conversion operation. If the operation is a numeric conversion, it overflows silently if the converted value does not fit the target type. - /// + /// A cast or conversion operation, such as (SampleType)obj in C#or CType(obj, SampleType) in Visual Basic. For a numeric conversion, if the converted value is too large for the destination type, no exception is thrown. Convert, - /// - /// A node that represents a cast or conversion operation. If the operation is a numeric conversion, an exception is thrown if the converted value does not fit the target type. - /// + /// A cast or conversion operation, such as (SampleType)obj in C#or CType(obj, SampleType) in Visual Basic. For a numeric conversion, if the converted value does not fit the destination type, an exception is thrown. ConvertChecked, - /// - /// A node that represents arithmetic division. - /// + /// A division operation, such as (a / b), for numeric operands. Divide, - /// - /// A node that represents an equality comparison. - /// + /// A node that represents an equality comparison, such as (a == b) in C# or (a = b) in Visual Basic. Equal, - /// - /// A node that represents a bitwise XOR operation. - /// + /// A bitwise or logical operation, such as (a ^ b) in C# or (a Xor b) in Visual Basic. ExclusiveOr, - /// - /// A node that represents a "greater than" numeric comparison. - /// + /// A "greater than" comparison, such as (a > b). GreaterThan, - /// - /// A node that represents a "greater than or equal" numeric comparison. - /// + /// A "greater than or equal to" comparison, such as (a >= b). GreaterThanOrEqual, - /// - /// A node that represents applying a delegate or lambda expression to a list of argument expressions. - /// + /// An operation that invokes a delegate or lambda expression, such as sampleDelegate.Invoke(). Invoke, - /// - /// A node that represents a lambda expression. - /// + /// A lambda expression, such as a => a + a in C# or Function(a) a + a in Visual Basic. Lambda, - /// - /// A node that represents a bitwise left-shift operation. - /// + /// A bitwise left-shift operation, such as (a << b). LeftShift, - /// - /// A node that represents a "less than" numeric comparison. - /// + /// A "less than" comparison, such as (a < b). LessThan, - /// - /// A node that represents a "less than or equal" numeric comparison. - /// + /// A "less than or equal to" comparison, such as (a <= b). LessThanOrEqual, - /// - /// A node that represents creating a new IEnumerable object and initializing it from a list of elements. - /// + /// An operation that creates a new object and initializes it from a list of elements, such as new List<SampleType>(){ a, b, c } in C# or Dim sampleList = { a, b, c } in Visual Basic. ListInit, - /// - /// A node that represents reading from a field or property. - /// + /// An operation that reads from a field or property, such as obj.SampleProperty. MemberAccess, - /// - /// A node that represents creating a new object and initializing one or more of its members. - /// + /// An operation that creates a new object and initializes one or more of its members, such as new Point { X = 1, Y = 2 } in C# or New Point With {.X = 1, .Y = 2} in Visual Basic. MemberInit, - /// - /// A node that represents an arithmetic remainder operation. - /// + /// An arithmetic remainder operation, such as (a % b) in C# or (a Mod b) in Visual Basic. Modulo, - /// - /// A node that represents arithmetic multiplication without overflow checking. - /// + /// A multiplication operation, such as (a * b), without overflow checking, for numeric operands. Multiply, - /// - /// A node that represents arithmetic multiplication with overflow checking. - /// + /// An multiplication operation, such as (a * b), that has overflow checking, for numeric operands. MultiplyChecked, - /// - /// A node that represents an arithmetic negation operation. - /// + /// An arithmetic negation operation, such as (-a). The object a should not be modified in place. Negate, - /// - /// A node that represents a unary plus operation. The result of a predefined unary plus operation is simply the value of the operand, but user-defined implementations may have non-trivial results. - /// + /// A unary plus operation, such as (+a). The result of a predefined unary plus operation is the value of the operand, but user-defined implementations might have unusual results. UnaryPlus, - /// - /// A node that represents an arithmetic negation operation that has overflow checking. - /// + /// An arithmetic negation operation, such as (-a), that has overflow checking. The object a should not be modified in place. NegateChecked, - /// - /// A node that represents calling a constructor to create a new object. - /// + /// An operation that calls a constructor to create a new object, such as new SampleType(). New, - /// - /// A node that represents creating a new one-dimensional array and initializing it from a list of elements. - /// + /// An operation that creates a new one-dimensional array and initializes it from a list of elements, such as new SampleType[]{a, b, c} in C# or New SampleType(){a, b, c} in Visual Basic. NewArrayInit, - /// - /// A node that represents creating a new array where the bounds for each dimension are specified. - /// + /// An operation that creates a new array, in which the bounds for each dimension are specified, such as new SampleType[dim1, dim2] in C# or New SampleType(dim1, dim2) in Visual Basic. NewArrayBounds, - /// - /// A node that represents a bitwise complement operation. - /// + /// A bitwise complement or logical negation operation. In C#, it is equivalent to (~a) for integral types and to (!a) for Boolean values. In Visual Basic, it is equivalent to (Not a). The object a should not be modified in place. Not, - /// - /// A node that represents an inequality comparison. - /// + /// An inequality comparison, such as (a != b) in C# or (a <> b) in Visual Basic. NotEqual, - /// - /// A node that represents a bitwise OR operation. - /// + /// A bitwise or logical operation, such as (a | b) in C# or (a Or b) in Visual Basic. Or, - /// - /// A node that represents a short-circuiting conditional OR operation. - /// + /// A short-circuiting conditional operation, such as (a || b) in C# or (a OrElse b) in Visual Basic. OrElse, - /// - /// A node that represents a reference to a parameter or variable defined in the context of the expression. - /// + /// A reference to a parameter or variable that is defined in the context of the expression. For more information, see . Parameter, - /// - /// A node that represents raising a number to a power. - /// + /// A mathematical operation that raises a number to a power, such as (a ^ b) in Visual Basic. Power, - /// - /// A node that represents an expression that has a constant value of type Expression. A Quote node can contain references to parameters defined in the context of the expression it represents. - /// + /// An expression that has a constant value of type . A node can contain references to parameters that are defined in the context of the expression it represents. Quote, - /// - /// A node that represents a bitwise right-shift operation. - /// + /// A bitwise right-shift operation, such as (a >> b). RightShift, - /// - /// A node that represents arithmetic subtraction without overflow checking. - /// + /// A subtraction operation, such as (a - b), without overflow checking, for numeric operands. Subtract, - /// - /// A node that represents arithmetic subtraction with overflow checking. - /// + /// An arithmetic subtraction operation, such as (a - b), that has overflow checking, for numeric operands. SubtractChecked, - /// - /// A node that represents an explicit reference or boxing conversion where null reference (Nothing in Visual Basic) is supplied if the conversion fails. - /// + /// An explicit reference or boxing conversion in which is supplied if the conversion fails, such as (obj as SampleType) in C# or TryCast(obj, SampleType) in Visual Basic. TypeAs, - /// - /// A node that represents a type test. - /// + /// A type test, such as obj is SampleType in C# or TypeOf obj is SampleType in Visual Basic. TypeIs, - /// - /// A node that represents an assignment. - /// + /// An assignment operation, such as (a = b). Assign, - /// - /// A node that represents a block of expressions. - /// + /// A block of expressions. Block, - /// - /// A node that represents a debugging information. - /// + /// Debugging information. DebugInfo, - /// - /// A node that represents a unary decrement. - /// + /// A unary decrement operation, such as (a - 1) in C# and Visual Basic. The object a should not be modified in place. Decrement, - /// - /// A node that represents a dynamic operation. - /// + /// A dynamic operation. Dynamic, - /// - /// A node that represents a default value. - /// + /// A default value. Default, - /// - /// A node that represents an extension expression. - /// + /// An extension expression. Extension, - /// - /// A node that represents a goto. - /// + /// A "go to" expression, such as goto Label in C# or GoTo Label in Visual Basic. Goto, - /// - /// A node that represents a unary increment. - /// + /// A unary increment operation, such as (a + 1) in C# and Visual Basic. The object a should not be modified in place. Increment, - /// - /// A node that represents an index operation. - /// + /// An index operation or an operation that accesses a property that takes arguments. Index, - /// - /// A node that represents a label. - /// + /// A label. Label, - /// - /// A node that represents a list of runtime variables. - /// + /// A list of run-time variables. For more information, see . RuntimeVariables, - /// - /// A node that represents a loop. - /// + /// A loop, such as for or while. Loop, - /// - /// A node that represents a switch operation. - /// + /// A switch operation, such as in C# or in Visual Basic. Switch, - /// - /// A node that represents a throwing of an exception. - /// + /// An operation that throws an exception, such as throw new Exception(). Throw, - /// - /// A node that represents a try-catch expression. - /// + /// A expression. Try, - /// - /// A node that represents an unbox value type operation. - /// + /// An unbox value type operation, such as and instructions in MSIL. Unbox, - /// - /// A node that represents an arithmetic addition compound assignment without overflow checking. - /// + /// An addition compound assignment operation, such as (a += b), without overflow checking, for numeric operands. AddAssign, - /// - /// A node that represents a bitwise AND compound assignment. - /// + /// A bitwise or logical compound assignment operation, such as (a &= b) in C#. AndAssign, - /// - /// A node that represents an arithmetic division compound assignment . - /// + /// An division compound assignment operation, such as (a /= b), for numeric operands. DivideAssign, - /// - /// A node that represents a bitwise XOR compound assignment. - /// + /// A bitwise or logical compound assignment operation, such as (a ^= b) in C#. ExclusiveOrAssign, - /// - /// A node that represents a bitwise left-shift compound assignment. - /// + /// A bitwise left-shift compound assignment, such as (a <<= b). LeftShiftAssign, - /// - /// A node that represents an arithmetic remainder compound assignment. - /// + /// An arithmetic remainder compound assignment operation, such as (a %= b) in C#. ModuloAssign, - /// - /// A node that represents arithmetic multiplication compound assignment without overflow checking. - /// + /// A multiplication compound assignment operation, such as (a *= b), without overflow checking, for numeric operands. MultiplyAssign, - /// - /// A node that represents a bitwise OR compound assignment. - /// + /// A bitwise or logical compound assignment, such as (a |= b) in C#. OrAssign, - /// - /// A node that represents raising a number to a power compound assignment. - /// + /// A compound assignment operation that raises a number to a power, such as (a ^= b) in Visual Basic. PowerAssign, - /// - /// A node that represents a bitwise right-shift compound assignment. - /// + /// A bitwise right-shift compound assignment operation, such as (a >>= b). RightShiftAssign, - /// - /// A node that represents arithmetic subtraction compound assignment without overflow checking. - /// + /// A subtraction compound assignment operation, such as (a -= b), without overflow checking, for numeric operands. SubtractAssign, - /// - /// A node that represents an arithmetic addition compound assignment with overflow checking. - /// + /// An addition compound assignment operation, such as (a += b), with overflow checking, for numeric operands. AddAssignChecked, - /// - /// A node that represents arithmetic multiplication compound assignment with overflow checking. - /// + /// A multiplication compound assignment operation, such as (a *= b), that has overflow checking, for numeric operands. MultiplyAssignChecked, - /// - /// A node that represents arithmetic subtraction compound assignment with overflow checking. - /// + /// A subtraction compound assignment operation, such as (a -= b), that has overflow checking, for numeric operands. SubtractAssignChecked, - /// - /// A node that represents an unary prefix increment. - /// + /// A unary prefix increment, such as (++a). The object a should be modified in place. PreIncrementAssign, - /// - /// A node that represents an unary prefix decrement. - /// + /// A unary prefix decrement, such as (--a). The object a should be modified in place. PreDecrementAssign, - /// - /// A node that represents an unary postfix increment. - /// + /// A unary postfix increment, such as (a++). The object a should be modified in place. PostIncrementAssign, - /// - /// A node that represents an unary postfix decrement. - /// + /// A unary postfix decrement, such as (a--). The object a should be modified in place. PostDecrementAssign, - /// - /// A node that represents an exact type test. - /// + /// An exact type test. TypeEqual, - /// - /// A node that represents a ones complement. - /// + /// A ones complement operation, such as (~a) in C#. OnesComplement, - /// - /// A node that represents a true condition value. - /// + /// A condition value. IsTrue, - /// - /// A node that represents a false condition value. - /// + /// A condition value. IsFalse, } } diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionVisitor.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionVisitor.cs index 92e210f97690bb..9025ab6cd32f37 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionVisitor.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionVisitor.cs @@ -8,38 +8,24 @@ namespace System.Linq.Expressions { - /// - /// Represents a visitor or rewriter for expression trees. - /// - /// - /// This class is designed to be inherited to create more specialized - /// classes whose functionality requires traversing, examining or copying - /// an expression tree. - /// + /// Represents a visitor or rewriter for expression trees. + /// This class is designed to be inherited to create more specialized classes whose functionality requires traversing, examining or copying an expression tree. public abstract class ExpressionVisitor { - /// - /// Initializes a new instance of . - /// + /// Initializes a new instance of . protected ExpressionVisitor() { } - /// - /// Dispatches the expression to one of the more specialized visit methods in this class. - /// + /// Dispatches the expression to one of the more specialized visit methods in this class. /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. [return: NotNullIfNotNull("node")] public virtual Expression? Visit(Expression? node) => node?.Accept(this); - /// - /// Dispatches the list of expressions to one of the more specialized visit methods in this class. - /// + /// Dispatches the list of expressions to one of the more specialized visit methods in this class. /// The expressions to visit. - /// The modified expression list, if any of the elements were modified; - /// otherwise, returns the original expression list. + /// The modified expression list, if any one of the elements were modified; otherwise, returns the original expression list. public ReadOnlyCollection Visit(ReadOnlyCollection nodes) { ContractUtils.RequiresNotNull(nodes, nameof(nodes)); @@ -79,15 +65,11 @@ public ReadOnlyCollection Visit(ReadOnlyCollection nodes return ExpressionVisitorUtils.VisitParameters(this, nodes, callerName); } - /// - /// Visits all nodes in the collection using a specified element visitor. - /// + /// Visits all nodes in the collection using a specified element visitor. /// The type of the nodes. /// The nodes to visit. - /// A delegate that visits a single element, - /// optionally replacing it with a new element. - /// The modified node list, if any of the elements were modified; - /// otherwise, returns the original node list. + /// A delegate that visits a single element, optionally replacing it with a new element. + /// The modified node list, if any of the elements were modified; otherwise, returns the original node list. public static ReadOnlyCollection Visit(ReadOnlyCollection nodes, Func elementVisitor) { ContractUtils.RequiresNotNull(nodes, nameof(nodes)); @@ -117,15 +99,12 @@ public static ReadOnlyCollection Visit(ReadOnlyCollection nodes, Func(newNodes); } - /// - /// Visits an expression, casting the result back to the original expression type. - /// + /// Visits an expression, casting the result back to the original expression type. /// The type of the expression. /// The expression to visit. /// The name of the calling method; used to report to report a better error message. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. - /// The visit method for this node returned a different type. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. + /// The visit method for this node returned a different type. [return: NotNullIfNotNull("node")] public T? VisitAndConvert(T? node, string? callerName) where T : Expression { @@ -141,15 +120,12 @@ public static ReadOnlyCollection Visit(ReadOnlyCollection nodes, Func - /// Visits an expression, casting the result back to the original expression type. - /// - /// The type of the expression. - /// The expression to visit. - /// The name of the calling method; used to report to report a better error message. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. - /// The visit method for this node returned a different type. + /// Visits all expressions in the collection, casting the results back to the original expression type. + /// The type of the expressions. + /// The expressions to visit. + /// The name of the calling method; used to report a better error message. + /// The modified expression collection, if any expression was modified; otherwise, returns the original expression collection. + /// The visit method for one of the expressions returned a different type. public ReadOnlyCollection VisitAndConvert(ReadOnlyCollection nodes, string? callerName) where T : Expression { ContractUtils.RequiresNotNull(nodes, nameof(nodes)); @@ -183,12 +159,9 @@ public ReadOnlyCollection VisitAndConvert(ReadOnlyCollection nodes, str return new TrueReadOnlyCollection(newNodes); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitBinary(BinaryExpression node) { // Walk children in evaluation order: left, conversion, right @@ -202,12 +175,9 @@ protected internal virtual Expression VisitBinary(BinaryExpression node) ); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitBlock(BlockExpression node) { Expression[]? nodes = ExpressionVisitorUtils.VisitBlockExpressions(this, node); @@ -221,84 +191,59 @@ protected internal virtual Expression VisitBlock(BlockExpression node) return node.Rewrite(v, nodes!); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitConditional(ConditionalExpression node) { return node.Update(Visit(node.Test), Visit(node.IfTrue), Visit(node.IfFalse)); } - /// - /// Visits the . - /// + /// Visits the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitConstant(ConstantExpression node) { return node; } - /// - /// Visits the . - /// + /// Visits the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitDebugInfo(DebugInfoExpression node) { return node; } - /// - /// Visits the . - /// + /// Visits the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitDefault(DefaultExpression node) { return node; } - /// - /// Visits the children of the extension expression. - /// + /// Visits the children of the extension expression. /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. - /// - /// This can be overridden to visit or rewrite specific extension nodes. - /// If it is not overridden, this method will call , - /// which gives the node a chance to walk its children. By default, - /// will try to reduce the node. - /// + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. + /// This can be overridden to visit or rewrite specific extension nodes. + /// If it is not overridden, this method will call , which gives the node a chance to walk its children. By default, will try to reduce the node. protected internal virtual Expression VisitExtension(Expression node) { return node.VisitChildren(this); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitGoto(GotoExpression node) { return node.Update(VisitLabelTarget(node.Target), Visit(node.Value)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitInvocation(InvocationExpression node) { Expression e = Visit(node.Expression); @@ -311,36 +256,27 @@ protected internal virtual Expression VisitInvocation(InvocationExpression node) return node.Rewrite(e, a); } - /// - /// Visits the . - /// + /// Visits the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. [return: NotNullIfNotNull("node")] protected virtual LabelTarget? VisitLabelTarget(LabelTarget? node) { return node; } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitLabel(LabelExpression node) { return node.Update(VisitLabelTarget(node.Target), Visit(node.DefaultValue)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The type of the delegate. /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitLambda(Expression node) { Expression body = Visit(node.Body); @@ -354,34 +290,25 @@ protected internal virtual Expression VisitLambda(Expression node) return node.Rewrite(body, parameters); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitLoop(LoopExpression node) { return node.Update(VisitLabelTarget(node.BreakLabel), VisitLabelTarget(node.ContinueLabel), Visit(node.Body)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitMember(MemberExpression node) { return node.Update(Visit(node.Expression)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitIndex(IndexExpression node) { Expression o = Visit(node.Object)!; @@ -394,12 +321,9 @@ protected internal virtual Expression VisitIndex(IndexExpression node) return node.Rewrite(o, a); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitMethodCall(MethodCallExpression node) { Expression o = Visit(node.Object)!; @@ -412,23 +336,17 @@ protected internal virtual Expression VisitMethodCall(MethodCallExpression node) return node.Rewrite(o, a); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitNewArray(NewArrayExpression node) { return node.Update(Visit(node.Expressions)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitNew(NewExpression node) { Expression[]? a = VisitArguments(node); @@ -440,45 +358,33 @@ protected internal virtual Expression VisitNew(NewExpression node) return node.Update(a); } - /// - /// Visits the . - /// + /// Visits the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitParameter(ParameterExpression node) { return node; } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitRuntimeVariables(RuntimeVariablesExpression node) { return node.Update(VisitAndConvert(node.Variables, nameof(VisitRuntimeVariables))); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected virtual SwitchCase VisitSwitchCase(SwitchCase node) { return node.Update(Visit(node.TestValues), Visit(node.Body)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitSwitch(SwitchExpression node) { return ValidateSwitch( @@ -491,23 +397,17 @@ protected internal virtual Expression VisitSwitch(SwitchExpression node) ); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected virtual CatchBlock VisitCatchBlock(CatchBlock node) { return node.Update(VisitAndConvert(node.Variable, nameof(VisitCatchBlock)), Visit(node.Filter), Visit(node.Body)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitTry(TryExpression node) { return node.Update( @@ -518,34 +418,25 @@ protected internal virtual Expression VisitTry(TryExpression node) ); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitTypeBinary(TypeBinaryExpression node) { return node.Update(Visit(node.Expression)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitUnary(UnaryExpression node) { return ValidateUnary(node, node.Update(Visit(node.Operand))); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitMemberInit(MemberInitExpression node) { return node.Update( @@ -554,12 +445,9 @@ protected internal virtual Expression VisitMemberInit(MemberInitExpression node) ); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitListInit(ListInitExpression node) { return node.Update( @@ -568,23 +456,17 @@ protected internal virtual Expression VisitListInit(ListInitExpression node) ); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected virtual ElementInit VisitElementInit(ElementInit node) { return node.Update(Visit(node.Arguments)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected virtual MemberBinding VisitMemberBinding(MemberBinding node) => node.BindingType switch { @@ -594,34 +476,25 @@ protected virtual MemberBinding VisitMemberBinding(MemberBinding node) => _ => throw Error.UnhandledBindingType(node.BindingType), }; - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected virtual MemberAssignment VisitMemberAssignment(MemberAssignment node) { return node.Update(Visit(node.Expression)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding node) { return node.Update(Visit(node.Bindings, VisitMemberBinding)); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected virtual MemberListBinding VisitMemberListBinding(MemberListBinding node) { return node.Update(Visit(node.Initializers, VisitElementInit)); @@ -703,12 +576,9 @@ private static void ValidateChildType(Type before, Type after, string methodName throw Error.MustRewriteChildToSameType(before, after, methodName); } - /// - /// Visits the children of the . - /// + /// Visits the children of the . /// The expression to visit. - /// The modified expression, if it or any subexpression was modified; - /// otherwise, returns the original expression. + /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. protected internal virtual Expression VisitDynamic(DynamicExpression node) { Expression[]? a = VisitArguments((IArgumentProvider)node); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/GotoExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/GotoExpression.cs index 9c1a38f9a8a458..d2330ce118dcf9 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/GotoExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/GotoExpression.cs @@ -6,32 +6,24 @@ namespace System.Linq.Expressions { - /// - /// Specifies what kind of jump this represents. - /// + /// Specifies what kind of jump this represents. public enum GotoExpressionKind { - /// - /// A that represents a jump to some location. - /// + /// A that represents a jump to some location. Goto, - /// - /// A that represents a return statement. - /// + /// A that represents a return statement. Return, - /// - /// A that represents a break statement. - /// + /// A that represents a break statement. Break, - /// - /// A that represents a continue statement. - /// + /// A that represents a continue statement. Continue, } - /// - /// Represents an unconditional jump. This includes return statements, break and continue statements, and other jumps. - /// + /// Represents an unconditional jump. This includes return statements, break and continue statements, and other jumps. + /// + /// The following example demonstrates how to create an expression that contains a object by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet45"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet45"::: [DebuggerTypeProxy(typeof(GotoExpressionProxy))] public sealed class GotoExpression : Expression { @@ -43,50 +35,38 @@ internal GotoExpression(GotoExpressionKind kind, LabelTarget target, Expression? Type = type; } - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type { get; } - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.Goto; - /// - /// The value passed to the target, or null if the target is of type - /// System.Void. - /// + /// The value passed to the target, or null if the target is of type System.Void. + /// The object representing the value passed to the target or null. public Expression? Value { get; } - /// - /// The target label where this node jumps to. - /// + /// The target label where this node jumps to. + /// The object representing the target label for this node. public LabelTarget Target { get; } - /// - /// The kind of the goto. For information purposes only. - /// + /// The kind of the "go to" expression. Serves information purposes only. + /// The object representing the kind of the "go to" expression. public GotoExpressionKind Kind { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitGoto(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public GotoExpression Update(LabelTarget target, Expression? value) { if (target == Target && value == Value) @@ -97,239 +77,160 @@ public GotoExpression Update(LabelTarget target, Expression? value) } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a representing a break statement. - /// - /// The that the will jump to. - /// - /// A with equal to , - /// the property set to , and a null value to be passed to the target label upon jumping. - /// + /// Creates a representing a break statement. + /// The that the will jump to. + /// A with equal to Break, the property set to , and a null value to be passed to the target label upon jumping. + /// + /// The following example demonstrates how to create an expression that contains a object that uses the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet44"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet44"::: public static GotoExpression Break(LabelTarget target) { return MakeGoto(GotoExpressionKind.Break, target, null, typeof(void)); } - /// - /// Creates a representing a break statement. The value passed to the label upon jumping can be specified. - /// - /// The that the will jump to. + /// Creates a representing a break statement. The value passed to the label upon jumping can be specified. + /// The that the will jump to. /// The value that will be passed to the associated label upon jumping. - /// - /// A with equal to , - /// the property set to , - /// and to be passed to the target label upon jumping. - /// + /// A with equal to Break, the property set to , and to be passed to the target label upon jumping. public static GotoExpression Break(LabelTarget target, Expression? value) { return MakeGoto(GotoExpressionKind.Break, target, value, typeof(void)); } - /// - /// Creates a representing a break statement with the specified type. - /// - /// The that the will jump to. - /// A to set the property equal to. - /// - /// A with equal to , - /// the property set to , - /// and the property set to . - /// + /// Creates a representing a break statement with the specified type. + /// The that the will jump to. + /// An to set the property equal to. + /// A with equal to Break, the property set to , and the property set to . public static GotoExpression Break(LabelTarget target, Type type) { return MakeGoto(GotoExpressionKind.Break, target, null, type); } - /// - /// Creates a representing a break statement with the specified type. - /// The value passed to the label upon jumping can be specified. - /// - /// The that the will jump to. + /// Creates a representing a break statement with the specified type. The value passed to the label upon jumping can be specified. + /// The that the will jump to. /// The value that will be passed to the associated label upon jumping. - /// A to set the property equal to. - /// - /// A with equal to , - /// the property set to , - /// the property set to , - /// and to be passed to the target label upon jumping. - /// + /// An to set the property equal to. + /// A with equal to Break, the property set to , the property set to , and to be passed to the target label upon jumping. public static GotoExpression Break(LabelTarget target, Expression? value, Type type) { return MakeGoto(GotoExpressionKind.Break, target, value, type); } - /// - /// Creates a representing a continue statement. - /// - /// The that the will jump to. - /// - /// A with equal to , - /// the property set to , - /// and a null value to be passed to the target label upon jumping. - /// + /// Creates a representing a continue statement. + /// The that the will jump to. + /// A with equal to Continue, the property set to , and a null value to be passed to the target label upon jumping. + /// + /// The following example demonstrates how to create a loop expression that uses the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet46"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet46"::: public static GotoExpression Continue(LabelTarget target) { return MakeGoto(GotoExpressionKind.Continue, target, null, typeof(void)); } - /// - /// Creates a representing a continue statement with the specified type. - /// - /// The that the will jump to. - /// A to set the property equal to. - /// - /// A with equal to , - /// the property set to , - /// the property set to , - /// and a null value to be passed to the target label upon jumping. - /// + /// Creates a representing a continue statement with the specified type. + /// The that the will jump to. + /// An to set the property equal to. + /// A with equal to Continue, the property set to , the property set to , and a null value to be passed to the target label upon jumping. public static GotoExpression Continue(LabelTarget target, Type type) { return MakeGoto(GotoExpressionKind.Continue, target, null, type); } - /// - /// Creates a representing a return statement. - /// - /// The that the will jump to. - /// - /// A with equal to , - /// the property set to , - /// and a null value to be passed to the target label upon jumping. - /// + /// Creates a representing a return statement. + /// The that the will jump to. + /// A with equal to Return, the property set to , and a null value to be passed to the target label upon jumping. public static GotoExpression Return(LabelTarget target) { return MakeGoto(GotoExpressionKind.Return, target, null, typeof(void)); } - /// - /// Creates a representing a return statement with the specified type. - /// - /// The that the will jump to. - /// A to set the property equal to. - /// - /// A with equal to , - /// the property set to , - /// the property set to , - /// and a null value to be passed to the target label upon jumping. - /// + /// Creates a representing a return statement with the specified type. + /// The that the will jump to. + /// An to set the property equal to. + /// A with equal to Return, the property set to , the property set to , and a null value to be passed to the target label upon jumping. public static GotoExpression Return(LabelTarget target, Type type) { return MakeGoto(GotoExpressionKind.Return, target, null, type); } - /// - /// Creates a representing a return statement. The value passed to the label upon jumping can be specified. - /// - /// The that the will jump to. + /// Creates a representing a return statement. The value passed to the label upon jumping can be specified. + /// The that the will jump to. /// The value that will be passed to the associated label upon jumping. - /// - /// A with equal to , - /// the property set to , - /// and to be passed to the target label upon jumping. - /// + /// A with equal to Continue, the property set to , and to be passed to the target label upon jumping. + /// + /// The following example demonstrates how to create an expression that contains the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet43"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet43"::: public static GotoExpression Return(LabelTarget target, Expression? value) { return MakeGoto(GotoExpressionKind.Return, target, value, typeof(void)); } - /// - /// Creates a representing a return statement with the specified type. - /// The value passed to the label upon jumping can be specified. - /// - /// The that the will jump to. + /// Creates a representing a return statement with the specified type. The value passed to the label upon jumping can be specified. + /// The that the will jump to. /// The value that will be passed to the associated label upon jumping. - /// A to set the property equal to. - /// - /// A with equal to , - /// the property set to , - /// the property set to , - /// and to be passed to the target label upon jumping. - /// + /// An to set the property equal to. + /// A with equal to Continue, the property set to , the property set to , and to be passed to the target label upon jumping. public static GotoExpression Return(LabelTarget target, Expression? value, Type type) { return MakeGoto(GotoExpressionKind.Return, target, value, type); } - /// - /// Creates a representing a goto. - /// - /// The that the will jump to. - /// - /// A with equal to , - /// the property set to the specified value, - /// and a null value to be passed to the target label upon jumping. - /// + /// Creates a representing a "go to" statement. + /// The that the will jump to. + /// A with equal to Goto, the property set to the specified value, and a null value to be passed to the target label upon jumping. + /// + /// The following example demonstrates how to create an expression that contains a object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet45"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet45"::: public static GotoExpression Goto(LabelTarget target) { return MakeGoto(GotoExpressionKind.Goto, target, null, typeof(void)); } - /// - /// Creates a representing a goto with the specified type. - /// - /// The that the will jump to. - /// A to set the property equal to. - /// - /// A with equal to , - /// the property set to the specified value, - /// the property set to , - /// and a null value to be passed to the target label upon jumping. - /// + /// Creates a representing a "go to" statement with the specified type. + /// The that the will jump to. + /// An to set the property equal to. + /// A with equal to Goto, the property set to the specified value, the property set to , and a null value to be passed to the target label upon jumping. public static GotoExpression Goto(LabelTarget target, Type type) { return MakeGoto(GotoExpressionKind.Goto, target, null, type); } - /// - /// Creates a representing a goto. The value passed to the label upon jumping can be specified. - /// - /// The that the will jump to. + /// Creates a representing a "go to" statement. The value passed to the label upon jumping can be specified. + /// The that the will jump to. /// The value that will be passed to the associated label upon jumping. - /// - /// A with equal to , - /// the property set to , - /// and to be passed to the target label upon jumping. - /// + /// A with equal to Goto, the property set to , and to be passed to the target label upon jumping. public static GotoExpression Goto(LabelTarget target, Expression? value) { return MakeGoto(GotoExpressionKind.Goto, target, value, typeof(void)); } - /// - /// Creates a representing a goto with the specified type. - /// The value passed to the label upon jumping can be specified. - /// - /// The that the will jump to. + /// Creates a representing a "go to" statement with the specified type. The value passed to the label upon jumping can be specified. + /// The that the will jump to. /// The value that will be passed to the associated label upon jumping. - /// A to set the property equal to. - /// - /// A with equal to , - /// the property set to , - /// the property set to , - /// and to be passed to the target label upon jumping. - /// + /// An to set the property equal to. + /// A with equal to Goto, the property set to , the property set to , and to be passed to the target label upon jumping. public static GotoExpression Goto(LabelTarget target, Expression? value, Type type) { return MakeGoto(GotoExpressionKind.Goto, target, value, type); } - /// - /// Creates a representing a jump of the specified . - /// The value passed to the label upon jumping can also be specified. - /// - /// The of the . - /// The that the will jump to. + /// Creates a representing a jump of the specified . The value passed to the label upon jumping can also be specified. + /// The of the . + /// The that the will jump to. /// The value that will be passed to the associated label upon jumping. - /// A to set the property equal to. - /// - /// A with equal to , - /// the property set to , - /// the property set to , - /// and to be passed to the target label upon jumping. - /// + /// An to set the property equal to. + /// A with equal to , the property set to , the property set to , and to be passed to the target label upon jumping. public static GotoExpression MakeGoto(GotoExpressionKind kind, LabelTarget target, Expression? value, Type type) { ValidateGoto(target, ref value, nameof(target), nameof(value), type); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IArgumentProvider.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IArgumentProvider.cs index 6cfe48298ce26a..fbc4be1903a4f7 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IArgumentProvider.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IArgumentProvider.cs @@ -3,57 +3,25 @@ namespace System.Linq.Expressions { - /// - /// Interface for accessing the arguments of multiple tree nodes (, - /// , , , - /// , and ). - /// - /// - /// This enables two optimizations which reduce the size of the trees. The first is it enables - /// the nodes to hold onto an instead of a - /// . This saves the cost of allocating - /// the read-only collection for each node. The second is that it enables specialized subclasses to be - /// created which hold onto a specific number of arguments. These nodes can therefore avoid allocating - /// both a and an array for storing their - /// elements, thus saving 32 bytes per node. This technique is used by various nodes including - /// , , . - /// - /// Meanwhile the nodes can expose properties of s. - /// They do this by re-using one field for storing both the array or an element that would normally be stored - /// in the array. - /// - /// For the array case the collection is typed to instead - /// of . When the node is initially constructed - /// it is an array. When utilities in this library access the arguments it uses this interface. If a user - /// accesses the property the array is promoted to a . - /// - /// For the object case we store the first argument in a field typed to and when - /// the node is initially constructed this holds directly onto the of the - /// first argument. When utilities in this library access the arguments it again uses this interface - /// and the accessor for the first argument uses to return the object - /// which handles the or case. - /// When the user accesses the property the object field is updated to hold directly onto the - /// . - /// - /// It is important that properties consistently return the same - /// otherwise the rewriter used by expression - /// visitors will be broken and it would be a breaking change from LINQ v1. The problem is that currently - /// users can rely on object identity to tell if the node has changed. Storing the read-only collection in - /// an overloaded field enables us to both reduce memory usage as well as maintain compatibility and an - /// easy to use external API. - /// + /// Provides an internal interface for accessing the arguments of multiple tree nodes (DynamicExpression, ElementInit, MethodCallExpression, InvocationExpression, NewExpression, and IndexExpression). This API is for internal use only. + /// You should not use this API. It is public only due to assembly refactoring, and it exists only for internal performance optimizations. It enables two optimizations that reduce the size of the trees: + /// 1. It enables the nodes to hold onto an instead of a . This saves the cost of allocating the read-only collection for each node. + /// 2. It enables specialized subclasses to be created that hold on to a specific number of arguments (for example, `Block2`, `Block2`, `Block4`). Therefore, these nodes avoid allocating both a and an array for storing their elements, thus saving 32 bytes per node. This technique is used by various nodes, including , , and . + /// The expression tree nodes continue to expose the original LINQ properties of objects. They do this by reusing a field for storing both the array or an element that would normally be stored in the array. + /// For the array case, the collection is typed to instead of . When the node is initially constructed, it is an array. The compiler or utilities in this library access the elements through this interface. Accessing array elements promotes the array to a . + /// For the object case, the first argument is stored in a field typed to . When the node is initially constructed, this field holds the of the first argument. When the compiler and utilities in this library access the arguments, they again use this interface, and the accessor for the first argument uses the internal helper method to return the object that handles the or case. When the user accesses the , the object field is updated to hold directly onto the . + /// It is important that properties consistently return the same . Otherwise, the rewriter tree walker used by expression visitors will break. It is a breaking change from LINQ v1 to return different from the same node. Currently, users can rely on object identity to tell if the node has changed. Storing the in an overloaded field both reduces memory usage and maintains compatibility for the public API. public interface IArgumentProvider { - /// - /// Gets the argument expression with the specified . - /// - /// The index of the argument expression to get. - /// The expression representing the argument at the specified . + /// Returns the argument at , throwing if is out of bounds. This API is for internal use only. + /// The index of the argument. + /// The argument at index. + /// You should not use this API. It is only public due to assembly refactoring, and it is used internally for performance optimizations. Expression GetArgument(int index); - /// - /// Gets the number of argument expressions of the node. - /// + /// Returns the number of arguments to the expression tree node. This API is for internal use only. + /// The number of arguments to the expression tree node as . + /// You should not use this API. It is public only due to assembly refactoring, and it is used internally for performance optimizations. int ArgumentCount { get; diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IDynamicExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IDynamicExpression.cs index 147331e148d2e8..b9d796b74eaef9 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IDynamicExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IDynamicExpression.cs @@ -3,28 +3,20 @@ namespace System.Linq.Expressions { - /// - /// Interface implemented by expression nodes that represent a dynamically bound operation. - /// + /// Provides an internal interface for accessing the arguments of DynamicExpression tree nodes as well as CallSite and Rewriting functionality. You should not use this API. It is only public due to DLL refactoring and exists only for internal performance optimizations. public interface IDynamicExpression : IArgumentProvider { - /// - /// Gets the type of the delegate used by the CallSite. - /// + /// Gets the delegate type used by the CallSite, which is the type of the rules used in the dynamic expression's polymorphic inline cache. + /// The delegate type used by the CallSite. Type DelegateType { get; } - /// - /// Rewrite this node replacing the args with the provided values. The - /// number of the args needs to match the number of the current block. - /// - /// This helper is provided to allow re-writing of nodes to not depend on the specific - /// class of DynamicExpression which is being used. - /// + /// Rewrites this node replacing the dynamic expression's arguments with the provided values. The number of needs to match the number of the current expression. You should not use this type. It is only public due to assembly refactoring, and it is used internally for performance optimizations. This helper method allows re-writing of nodes to be independent of the specific implementation class deriving from DynamicExpression that is being used at the call site. + /// The arguments used to replace this node. + /// The rewritten node, but if no changes were made, then returns the same node. Expression Rewrite(Expression[] args); - /// - /// Creates a CallSite for the node. - /// + /// Optionally creates the CallSite and returns the CallSite for the DynamicExpression's polymorphic inline cache. You should not use this type. It is only public due to assembly refactoring, and it is used internally for performance optimizations. + /// The CallSite for the DynamicExpression's polymorphic inline cache. object CreateCallSite(); } } diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IndexExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IndexExpression.cs index 47c2a4d1ffe058..9c67eda3bd2234 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IndexExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/IndexExpression.cs @@ -12,9 +12,11 @@ namespace System.Linq.Expressions { - /// - /// Represents indexing a property or array. - /// + /// Represents indexing a property or array. + /// + /// The following code example shows how to create an object of the type and use it to change a value of an array element by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet20"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet20"::: [DebuggerTypeProxy(typeof(IndexExpressionProxy))] public sealed class IndexExpression : Expression, IArgumentProvider { @@ -36,16 +38,12 @@ internal IndexExpression( _arguments = arguments; } - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.Index; - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type { get @@ -58,32 +56,25 @@ public sealed override Type Type } } - /// - /// An object to index. - /// + /// An object to index. + /// The representing the object to index. public Expression? Object { get; } - /// - /// Gets the for the property if the expression represents an indexed property, returns null otherwise. - /// + /// Gets the for the property if the expression represents an indexed property, returns null otherwise. + /// The for the property if the expression represents an indexed property, otherwise null. public PropertyInfo? Indexer { get; } - /// - /// Gets the arguments to be used to index the property or array. - /// + /// Gets the arguments that will be used to index the property or array. + /// The read-only collection containing the arguments that will be used to index the property or array. public ReadOnlyCollection Arguments { get { return ExpressionUtils.ReturnReadOnly(ref _arguments); } } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public IndexExpression Update(Expression @object, IEnumerable? arguments) { if (@object == Object && arguments != null) @@ -109,9 +100,9 @@ public IndexExpression Update(Expression @object, IEnumerable? argum /// public int ArgumentCount => _arguments.Count; - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitIndex(this); @@ -126,15 +117,18 @@ internal Expression Rewrite(Expression instance, Expression[]? arguments) } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates an that represents accessing an indexed property in an object. - /// - /// The object to which the property belongs. Should be null if the property is static(shared). - /// An representing the property to index. - /// An containing the arguments to be used to index the property. - /// The created . + /// Creates an that represents accessing an indexed property in an object. + /// The object to which the property belongs. It should be null if the property is ( in Visual Basic). + /// An representing the property to index. + /// An IEnumerable<Expression> (IEnumerable (Of Expression) in Visual Basic) that contains the arguments that will be used to index the property. + /// The created . public static IndexExpression MakeIndex(Expression instance, PropertyInfo? indexer, IEnumerable? arguments) { if (indexer != null) @@ -147,29 +141,28 @@ public static IndexExpression MakeIndex(Expression instance, PropertyInfo? index } } - #region ArrayAccess - - /// - /// Creates an to access an array. - /// + /// Creates an to access an array. /// An expression representing the array to index. - /// An array containing expressions used to index the array. - /// The expression representing the array can be obtained by using the method, - /// or through or . - /// The created . + /// An array that contains expressions used to index the array. + /// The created . + /// The expression that represents the array can be obtained by using the method, or through or . + /// For multidimensional arrays, use the method. + /// The following code example shows how to change a value of an array element by using the `ArrayAccess` method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet20"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet20"::: public static IndexExpression ArrayAccess(Expression array, params Expression[]? indexes) { return ArrayAccess(array, (IEnumerable?)indexes); } - /// - /// Creates an to access an array. - /// - /// An expression representing the array to index. - /// An containing expressions used to index the array. - /// The expression representing the array can be obtained by using the method, - /// or through or . - /// The created . + /// Creates an to access a multidimensional array. + /// An expression that represents the multidimensional array. + /// An containing expressions used to index the array. + /// The created . + /// The expression that represents the array can be obtained by using the method, or through or . + /// The following code example shows how to change the value of an element in a multidimensional array by using the `ArrayAccess` method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet21"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet21"::: public static IndexExpression ArrayAccess(Expression array, IEnumerable? indexes) { ExpressionUtils.RequiresCanRead(array, nameof(array)); @@ -198,17 +191,11 @@ public static IndexExpression ArrayAccess(Expression array, IEnumerable - /// Creates an representing the access to an indexed property. - /// + /// Creates an representing the access to an indexed property. /// The object to which the property belongs. If the property is static/shared, it must be null. /// The name of the indexer. - /// An array of objects that are used to index the property. - /// The created . + /// An array of objects that are used to index the property. + /// The created . [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static IndexExpression Property(Expression instance, string propertyName, params Expression[]? arguments) { @@ -336,27 +323,21 @@ private static bool IsCompatible(PropertyInfo pi, Expression[]? args) return true; } - #endregion - - /// - /// Creates an representing the access to an indexed property. - /// + /// Creates an representing the access to an indexed property. /// The object to which the property belongs. If the property is static/shared, it must be null. - /// The that represents the property to index. - /// An array of objects that are used to index the property. - /// The created . + /// The that represents the property to index. + /// An array of objects that are used to index the property. + /// The created . public static IndexExpression Property(Expression? instance, PropertyInfo indexer, params Expression[]? arguments) { return Property(instance, indexer, (IEnumerable?)arguments); } - /// - /// Creates an representing the access to an indexed property. - /// + /// Creates an representing the access to an indexed property. /// The object to which the property belongs. If the property is static/shared, it must be null. - /// The that represents the property to index. - /// An of objects that are used to index the property. - /// The created . + /// The that represents the property to index. + /// An of objects that are used to index the property. + /// The created . public static IndexExpression Property(Expression? instance, PropertyInfo indexer, IEnumerable? arguments) => MakeIndexProperty(instance, indexer, nameof(indexer), arguments.ToReadOnly()); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/InvocationExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/InvocationExpression.cs index a77ff636f8cf29..0b44fe0b241ed9 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/InvocationExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/InvocationExpression.cs @@ -10,9 +10,12 @@ namespace System.Linq.Expressions { - /// - /// Represents an expression that applies a delegate or lambda expression to a list of argument expressions. - /// + /// Represents an expression that applies a delegate or lambda expression to a list of argument expressions. + /// Use the factory methods to create an . + /// The of an is . + /// The following example creates an that represents invoking a lambda expression with specified arguments. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet6"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet6"::: [DebuggerTypeProxy(typeof(InvocationExpressionProxy))] public class InvocationExpression : Expression, IArgumentProvider { @@ -22,37 +25,26 @@ internal InvocationExpression(Expression expression, Type returnType) Type = returnType; } - /// - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type { get; } - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType => ExpressionType.Invoke; - /// - /// Gets the delegate or lambda expression to be applied. - /// + /// Gets the delegate or lambda expression to be applied. + /// An that represents the delegate to be applied. public Expression Expression { get; } - /// - /// Gets the arguments that the delegate or lambda expression is applied to. - /// + /// Gets the arguments that the delegate or lambda expression is applied to. + /// A of objects which represent the arguments that the delegate is applied to. public ReadOnlyCollection Arguments => GetOrMakeArguments(); - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public InvocationExpression Update(Expression expression, IEnumerable? arguments) { if (expression == Expression && arguments != null) @@ -95,9 +87,9 @@ public virtual int ArgumentCount } } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitInvocation(this); @@ -395,6 +387,11 @@ internal override InvocationExpression Rewrite(Expression lambda, Expression[]? #endregion + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { /// @@ -659,55 +656,47 @@ internal static InvocationExpression Invoke(Expression expression, Expression ar return new InvocationExpression5(expression, method.ReturnType, arg0, arg1, arg2, arg3, arg4); } - /// - /// Creates an that - /// applies a delegate or lambda expression to a list of argument expressions. - /// - /// - /// An that - /// applies the specified delegate or lambda expression to the provided arguments. - /// - /// - /// An that represents the delegate - /// or lambda expression to be applied. - /// - /// - /// An array of objects - /// that represent the arguments that the delegate or lambda expression is applied to. - /// - /// - /// is null. - /// - /// .Type does not represent a delegate type or an .-or-The property of an element of is not assignable to the type of the corresponding parameter of the delegate represented by . - /// - /// does not contain the same number of elements as the list of parameters for the delegate represented by . + /// Creates an that applies a delegate or lambda expression to a list of argument expressions. + /// An that represents the delegate or lambda expression to be applied. + /// An array of objects that represent the arguments that the delegate or lambda expression is applied to. + /// An that applies the specified delegate or lambda expression to the provided arguments. + /// is . + /// .Type does not represent a delegate type or an . + /// -or- + /// The property of an element of is not assignable to the type of the corresponding parameter of the delegate represented by . + /// does not contain the same number of elements as the list of parameters for the delegate represented by . + /// The property of the resulting represents the return type of the delegate that is represented by .Type. + /// The property of the resulting is empty if is . Otherwise, it contains the same elements as except that some of these objects may be *quoted*. + /// [!NOTE] + /// > An element will be quoted only if the corresponding parameter of the delegate represented by `expression` is of type . Quoting means the element is wrapped in a node. The resulting node is a whose property is the element of `arguments`. + /// ]]> + /// The following example demonstrates how to use the method to create an that represents the invocation of a lambda expression with specified arguments. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet6"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet6"::: public static InvocationExpression Invoke(Expression expression, params Expression[]? arguments) { return Invoke(expression, (IEnumerable?)arguments); } - /// - /// Creates an that - /// applies a delegate or lambda expression to a list of argument expressions. - /// - /// - /// An that - /// applies the specified delegate or lambda expression to the provided arguments. - /// - /// - /// An that represents the delegate - /// or lambda expression to be applied. - /// - /// - /// An of objects - /// that represent the arguments that the delegate or lambda expression is applied to. - /// - /// - /// is null. - /// - /// .Type does not represent a delegate type or an .-or-The property of an element of is not assignable to the type of the corresponding parameter of the delegate represented by . - /// - /// does not contain the same number of elements as the list of parameters for the delegate represented by . + /// Creates an that applies a delegate or lambda expression to a list of argument expressions. + /// An that represents the delegate or lambda expression to be applied to. + /// An that contains objects that represent the arguments that the delegate or lambda expression is applied to. + /// An that applies the specified delegate or lambda expression to the provided arguments. + /// is . + /// .Type does not represent a delegate type or an . + /// -or- + /// The property of an element of is not assignable to the type of the corresponding parameter of the delegate represented by . + /// does not contain the same number of elements as the list of parameters for the delegate represented by . + /// The property of the resulting represents the return type of the delegate that is represented by .Type. + /// The property of the resulting is empty if is . Otherwise, it contains the same elements as except that some of these objects may be *quoted*. + /// [!NOTE] + /// > An element will be quoted only if the corresponding parameter of the delegate represented by `expression` is of type . Quoting means the element is wrapped in a node. The resulting node is a whose property is the element of `arguments`. + /// ]]> + /// The following example demonstrates how to use the method to create an that represents the invocation of a lambda expression with specified arguments. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet6"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet6"::: public static InvocationExpression Invoke(Expression expression, IEnumerable? arguments) { IReadOnlyList argumentList = arguments as IReadOnlyList ?? arguments.ToReadOnly(); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LabelExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LabelExpression.cs index 36cd31ab466f74..3f21bd41a8e58f 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LabelExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LabelExpression.cs @@ -5,12 +5,7 @@ namespace System.Linq.Expressions { - /// - /// Represents a label, which can be placed in any context. If - /// it is jumped to, it will get the value provided by the corresponding - /// . Otherwise, it gets the value in . If the - /// equals System.Void, no value should be provided. - /// + /// Represents a label, which can be put in any context. If it is jumped to, it will get the value provided by the corresponding . Otherwise, it receives the value in . If the equals System.Void, no value should be provided. [DebuggerTypeProxy(typeof(LabelExpressionProxy))] public sealed class LabelExpression : Expression { @@ -20,45 +15,34 @@ internal LabelExpression(LabelTarget label, Expression? defaultValue) DefaultValue = defaultValue; } - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type => Target.Type; - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.Label; - /// - /// The which this label is associated with. - /// + /// The which this label is associated with. + /// The which this label is associated with. public LabelTarget Target { get; } - /// - /// The value of the when the label is reached through - /// normal control flow (e.g. is not jumped to). - /// + /// The value of the when the label is reached through regular control flow (for example, is not jumped to). + /// The Expression object representing the value of the . public Expression? DefaultValue { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitLabel(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result + /// This expression if no children are changed or an expression with the updated children. public LabelExpression Update(LabelTarget target, Expression? defaultValue) { if (target == Target && defaultValue == DefaultValue) @@ -69,24 +53,25 @@ public LabelExpression Update(LabelTarget target, Expression? defaultValue) } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a representing a label with no default value. - /// - /// The which this will be associated with. - /// A with no default value. + /// Creates a representing a label without a default value. + /// The which this will be associated with. + /// A without a default value. public static LabelExpression Label(LabelTarget target) { return Label(target, defaultValue: null); } - /// - /// Creates a representing a label with the given default value. - /// - /// The which this will be associated with. - /// The value of this when the label is reached through normal control flow. - /// A with the given default value. + /// Creates a representing a label with the given default value. + /// The which this will be associated with. + /// The value of this when the label is reached through regular control flow. + /// A with the given default value. public static LabelExpression Label(LabelTarget target, Expression? defaultValue) { ValidateGoto(target, ref defaultValue, nameof(target), nameof(defaultValue), type: null); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LabelTarget.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LabelTarget.cs index b8b8d33fd42097..bde0edab259b0a 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LabelTarget.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LabelTarget.cs @@ -5,9 +5,11 @@ namespace System.Linq.Expressions { - /// - /// Used to denote the target of a . - /// + /// Used to represent the target of a . + /// + /// The following example demonstrates how to create an expression that contains a object by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet43"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet43"::: public sealed class LabelTarget { internal LabelTarget(Type type, string? name) @@ -16,65 +18,65 @@ internal LabelTarget(Type type, string? name) Name = name; } - /// - /// Gets the name of the label. - /// + /// Gets the name of the label. + /// The name of the label. /// The label's name is provided for information purposes only. public string? Name { get; } - /// - /// The type of value that is passed when jumping to the label - /// (or System.Void if no value should be passed). - /// + /// The type of value that is passed when jumping to the label (or if no value should be passed). + /// The object representing the type of the value that is passed when jumping to the label or if no value should be passed public Type Type { get; } - /// - /// Returns a that represents the current . - /// - /// A that represents the current . + /// Returns a that represents the current . + /// A that represents the current . public override string ToString() { return string.IsNullOrEmpty(Name) ? "UnamedLabel" : Name; } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a representing a label with void type and no name. - /// - /// The new . + /// Creates a representing a label with void type and no name. + /// The new . + /// + /// The following example demonstrates how to create an expression that contains a object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet43"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet43"::: public static LabelTarget Label() { return Label(typeof(void), name: null); } - /// - /// Creates a representing a label with void type and the given name. - /// + /// Creates a representing a label with void type and the given name. /// The name of the label. - /// The new . + /// The new . public static LabelTarget Label(string? name) { return Label(typeof(void), name); } - /// - /// Creates a representing a label with the given type. - /// + /// Creates a representing a label with the given type. /// The type of value that is passed when jumping to the label. - /// The new . + /// The new . + /// + /// The following example demonstrates how to use a object in a loop expression. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet44"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet44"::: public static LabelTarget Label(Type type) { return Label(type, name: null); } - /// - /// Creates a representing a label with the given type and name. - /// + /// Creates a representing a label with the given type and name. /// The type of value that is passed when jumping to the label. /// The name of the label. - /// The new . + /// The new . public static LabelTarget Label(Type type, string? name) { ContractUtils.RequiresNotNull(type, nameof(type)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs index fc45b9c5ff81f8..59c675b51bb5c1 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs @@ -11,13 +11,13 @@ namespace System.Linq.Expressions { - /// - /// Creates a node. - /// This captures a block of code that is similar to a .NET method body. - /// - /// - /// Lambda expressions take input through parameters and are expected to be fully bound. - /// + /// Describes a lambda expression. This captures a block of code that is similar to a .NET method body. + /// The type represents a lambda expression in the form of an expression tree. The type, which derives from and captures the type of the lambda expression more explicitly, can also be used to represent a lambda expression. At runtime, an expression tree node that represents a lambda expression is always of type . + /// The value of the property of a is . + /// Use the factory methods to create a object. + /// The following example demonstrates how to create an expression that represents a lambda expression that adds 1 to the passed argument by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet42"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet42"::: [DebuggerTypeProxy(typeof(LambdaExpressionProxy))] public abstract class LambdaExpression : Expression, IParameterProvider { @@ -28,49 +28,39 @@ internal LambdaExpression(Expression body) _body = body; } - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type => TypeCore; internal abstract Type TypeCore { get; } internal abstract Type PublicType { get; } - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.Lambda; - /// - /// Gets the parameters of the lambda expression. - /// + /// Gets the parameters of the lambda expression. + /// A of objects that represent the parameters of the lambda expression. public ReadOnlyCollection Parameters => GetOrMakeParameters(); - /// - /// Gets the name of the lambda expression. - /// - /// Used for debugging purposes. + /// Gets the name of the lambda expression. + /// The name of the lambda expression. + /// Used for debugging. public string? Name => NameCore; internal virtual string? NameCore => null; - /// - /// Gets the body of the lambda expression. - /// + /// Gets the body of the lambda expression. + /// An that represents the body of the lambda expression. public Expression Body => _body; - /// - /// Gets the return type of the lambda expression. - /// + /// Gets the return type of the lambda expression. + /// The object representing the type of the lambda expression. public Type ReturnType => Type.GetInvokeMethod().ReturnType; - /// - /// Gets the value that indicates if the lambda expression will be compiled with - /// tail call optimization. - /// + /// Gets the value that indicates if the lambda expression will be compiled with the tail call optimization. + /// if the lambda expression will be compiled with the tail call optimization; otherwise, . public bool TailCall => TailCallCore; internal virtual bool TailCallCore => false; @@ -135,10 +125,9 @@ private static MethodInfo GetDerivedCompileMethod(Type lambdaExpressionType) return result; } - /// - /// Produces a delegate that represents the lambda expression. - /// - /// A delegate containing the compiled version of the lambda. + /// Produces a delegate that represents the lambda expression. + /// A that contains the compiled version of the lambda expression. + /// The method can be used to convert a expression tree into the delegate that it represents. public Delegate Compile() { #if FEATURE_COMPILE @@ -148,11 +137,9 @@ public Delegate Compile() #endif } - /// - /// Produces a delegate that represents the lambda expression. - /// - /// A that indicates if the expression should be compiled to an interpreted form, if available. - /// A delegate containing the compiled version of the lambda. + /// Produces an interpreted or compiled delegate that represents the lambda expression. + /// to indicate that the expression should be compiled to an interpreted form, if it's available; otherwise, . + /// A delegate that represents the compiled lambda expression described by the object. public Delegate Compile(bool preferInterpretation) { #if FEATURE_COMPILE && FEATURE_INTERPRET @@ -184,10 +171,7 @@ public void CompileToMethod(System.Reflection.Emit.MethodBuilder method) #if FEATURE_COMPILE internal abstract LambdaExpression Accept(Compiler.StackSpiller spiller); #endif - - /// - /// Produces a delegate that represents the lambda expression. - /// + /// Produces a delegate that represents the lambda expression. /// Debugging information generator used by the compiler to mark sequence points and annotate local variables. /// A delegate containing the compiled version of the lambda. public Delegate Compile(DebugInfoGenerator debugInfoGenerator) @@ -196,14 +180,23 @@ public Delegate Compile(DebugInfoGenerator debugInfoGenerator) } } - /// - /// Defines a node. - /// This captures a block of code that is similar to a .NET method body. - /// - /// The type of the delegate. - /// - /// Lambda expressions take input through parameters and are expected to be fully bound. - /// + /// Represents a strongly typed lambda expression as a data structure in the form of an expression tree. This class cannot be inherited. + /// The type of the delegate that the represents. + /// When a lambda expression is assigned to a variable, field, or parameter whose type is , the compiler emits instructions to build an expression tree. + /// [!NOTE] + /// > A conversion from a lambda expression to type `Expression` (`Expression(Of D)` in Visual Basic) exists if a conversion from the lambda expression to a delegate of type `D` exists. However, the conversion may fail, for example, if the body of the lambda expression is a block. This means that delegates and expression trees behave similarly with regard to overload resolution. + /// ]]> + /// The expression tree is an in-memory data representation of the lambda expression. The expression tree makes the structure of the lambda expression transparent and explicit. You can interact with the data in the expression tree just as you can with any other data structure. + /// The ability to treat expressions as data structures enables APIs to receive user code in a format that can be inspected, transformed, and processed in a custom manner. For example, the LINQ to SQL data access implementation uses this facility to translate expression trees to Transact-SQL statements that can be evaluated by the database. + /// Many standard query operators defined in the class have one or more parameters of type . + /// The of an is . + /// Use the or method to create an object. + /// The following code example demonstrates how to represent a lambda expression both as executable code in the form of a delegate and as data in the form of an expression tree. It also demonstrates how to turn the expression tree back into executable code by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.ExpressionT/CS/ExpressionT.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.ExpressionT/VB/ExpressionT.vb" id="Snippet1"::: + /// Lambda Expressions (C# Programming Guide) + /// Expression Trees public class Expression : LambdaExpression { internal Expression(Expression body) @@ -215,10 +208,13 @@ internal Expression(Expression body) internal override Type PublicType => typeof(Expression); - /// - /// Produces a delegate that represents the lambda expression. - /// - /// A delegate containing the compiled version of the lambda. + /// Compiles the lambda expression described by the expression tree into executable code and produces a delegate that represents the lambda expression. + /// A delegate of type that represents the compiled lambda expression described by the . + /// The method produces a delegate of type `TDelegate` at runtime. When that delegate is executed, it has the behavior described by the semantics of the . + /// The method can be used to obtain the value of any expression tree. First, create a lambda expression that has the expression as its body by using the method. Then call to obtain a delegate, and execute the delegate to obtain the value of the expression. + /// The following code example demonstrates how is used to execute an expression tree. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.ExpressionT/CS/ExpressionT.cs" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.ExpressionT/VB/ExpressionT.vb" id="Snippet2"::: public new TDelegate Compile() { #if FEATURE_COMPILE @@ -228,11 +224,9 @@ internal Expression(Expression body) #endif } - /// - /// Produces a delegate that represents the lambda expression. - /// - /// A that indicates if the expression should be compiled to an interpreted form, if available. - /// A delegate containing the compiled version of the lambda. + /// Compiles the lambda expression described by the expression tree into interpreted or compiled code and produces a delegate that represents the lambda expression. + /// to indicate that the expression should be compiled to an interpreted form, if it is available; otherwise. + /// A delegate that represents the compiled lambda expression described by the . public new TDelegate Compile(bool preferInterpretation) { #if FEATURE_COMPILE && FEATURE_INTERPRET @@ -244,14 +238,10 @@ internal Expression(Expression body) return Compile(); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public Expression Update(Expression body, IEnumerable? parameters) { if (body == Body) @@ -293,9 +283,9 @@ internal virtual Expression Rewrite(Expression body, ParameterExpress throw ContractUtils.Unreachable; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitLambda(this); @@ -325,9 +315,7 @@ internal static Expression Create(Expression body, string? name, bool } #endif - /// - /// Produces a delegate that represents the lambda expression. - /// + /// Produces a delegate that represents the lambda expression. /// Debugging information generator used by the compiler to mark sequence points and annotate local variables. /// A delegate containing the compiled version of the lambda. public new TDelegate Compile(DebugInfoGenerator debugInfoGenerator) @@ -607,6 +595,11 @@ public FullExpression(Expression body, string? name, bool tailCall, IReadOnlyLis internal override bool TailCallCore { get; } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { /// @@ -643,78 +636,92 @@ internal static LambdaExpression CreateLambda(Type delegateType, Expression body return fastPath(body, name, tailCall, parameters); } - /// - /// Creates an where the delegate type is known at compile time. - /// - /// The delegate type. - /// An to set the property equal to. - /// An array that contains objects to use to populate the collection. - /// An that has the property equal to and the and properties set to the specified values. + /// Creates an where the delegate type is known at compile time, with an array of parameter expressions. + /// A delegate type. + /// An to set the property equal to. + /// An array of objects to use to populate the collection. + /// An that has the property equal to and the and properties set to the specified values. + /// is . + /// -or- + /// One or more elements in are . + /// is not a delegate type. + /// -or- + /// .Type represents a type that is not assignable to the return type of . + /// -or- + /// does not contain the same number of elements as the list of parameters for . + /// -or- + /// The property of an element of is not assignable from the type of the corresponding parameter type of . + /// The number of parameters for the delegate type must equal the number of elements in . + /// The elements of must be reference equal to the parameter expressions in. + /// The property of the resulting object represents the type . If is , the property of the resulting object is an empty collection. public static Expression Lambda(Expression body, params ParameterExpression[]? parameters) { return Lambda(body, false, (IEnumerable?)parameters); } - /// - /// Creates an where the delegate type is known at compile time. - /// + /// Creates an where the delegate type is known at compile time, with a parameter that indicates whether tail call optimization will be applied, and an array of parameter expressions. /// The delegate type. - /// An to set the property equal to. - /// A that indicates if tail call optimization will be applied when compiling the created expression. - /// An array that contains objects to use to populate the collection. - /// An that has the property equal to and the and properties set to the specified values. + /// An to set the property equal to. + /// A that indicates if tail call optimization will be applied when compiling the created expression. + /// An array that contains objects to use to populate the collection. + /// An that has the property equal to and the and properties set to the specified values. public static Expression Lambda(Expression body, bool tailCall, params ParameterExpression[]? parameters) { return Lambda(body, tailCall, (IEnumerable?)parameters); } - /// - /// Creates an where the delegate type is known at compile time. - /// - /// The delegate type. - /// An to set the property equal to. - /// An that contains objects to use to populate the collection. - /// An that has the property equal to and the and properties set to the specified values. + /// Creates an where the delegate type is known at compile time, with an enumerable collection of parameter expressions. + /// A delegate type. + /// An to set the property equal to. + /// An that contains objects to use to populate the collection. + /// An that has the property equal to and the and properties set to the specified values. + /// is . + /// -or- + /// One or more elements in are . + /// is not a delegate type. + /// -or- + /// .Type represents a type that is not assignable to the return type of . + /// -or- + /// does not contain the same number of elements as the list of parameters for . + /// -or- + /// The property of an element of is not assignable from the type of the corresponding parameter type of . + /// The number of parameters for the delegate type must equal the number of elements in . + /// The elements of must be reference equal to the parameter expressions in . + /// The property of the resulting object represents the type . If is , the property of the resulting object is an empty collection. public static Expression Lambda(Expression body, IEnumerable? parameters) { return Lambda(body, null, false, parameters); } - /// - /// Creates an where the delegate type is known at compile time. - /// + /// Creates an where the delegate type is known at compile time, with a parameter that indicates whether tail call optimization will be applied, and an enumerable collection of parameter expressions. /// The delegate type. - /// An to set the property equal to. - /// A that indicates if tail call optimization will be applied when compiling the created expression. - /// An that contains objects to use to populate the collection. - /// An that has the property equal to and the and properties set to the specified values. + /// An to set the property equal to. + /// A that indicates if tail call optimization will be applied when compiling the created expression. + /// An that contains objects to use to populate the collection. + /// An that has the property equal to and the and properties set to the specified values. public static Expression Lambda(Expression body, bool tailCall, IEnumerable? parameters) { return Lambda(body, null, tailCall, parameters); } - /// - /// Creates an where the delegate type is known at compile time. - /// + /// Creates an where the delegate type is known at compile time, with the name for the lambda, and an enumerable collection of parameter expressions. /// The delegate type. - /// An to set the property equal to. - /// An that contains objects to use to populate the collection. - /// The name of the lambda. Used for generating debugging info. - /// An that has the property equal to and the and properties set to the specified values. + /// An to set the property equal to. + /// The name of the lambda. Used for generating debugging information. + /// An that contains objects to use to populate the collection. + /// An that has the property equal to and the and properties set to the specified values. public static Expression Lambda(Expression body, string? name, IEnumerable? parameters) { return Lambda(body, name, false, parameters); } - /// - /// Creates an where the delegate type is known at compile time. - /// + /// Creates an where the delegate type is known at compile time, with the name for the lambda, a parameter that indicates whether tail call optimization will be applied, and an enumerable collection of parameter expressions. /// The delegate type. - /// An to set the property equal to. + /// An to set the property equal to. /// The name of the lambda. Used for generating debugging info. - /// An that contains objects to use to populate the collection. - /// A that indicates if tail call optimization will be applied when compiling the created expression. - /// An that has the property equal to and the and properties set to the specified values. + /// A that indicates if tail call optimization will be applied when compiling the created expression. + /// An that contains objects to use to populate the collection. + /// An that has the property equal to and the and properties set to the specified values. public static Expression Lambda(Expression body, string? name, bool tailCall, IEnumerable? parameters) { ReadOnlyCollection parameterList = parameters.ToReadOnly(); @@ -726,122 +733,140 @@ public static Expression Lambda(Expression body, string? n #endif } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. - /// An array that contains objects to use to populate the collection. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a by first constructing a delegate type from the expression body, and an array of parameter expressions. It can be used when the delegate type is not known at compile time. + /// An to set the property equal to. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// -or- + /// One or more elements of are . + /// contains more than sixteen elements. + /// The parameter must not have more than sixteen elements. + /// The elements of must be reference equal to the parameter expressions in . + /// This method constructs an appropriate delegate type from one of the `System.Func` generic delegates. It then passes the delegate type to one of the factory methods to create a . public static LambdaExpression Lambda(Expression body, params ParameterExpression[]? parameters) { return Lambda(body, false, (IEnumerable?)parameters); } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. - /// A that indicates if tail call optimization will be applied when compiling the created expression. - /// An array that contains objects to use to populate the collection. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a by first constructing a delegate type from the expression body, a parameter that indicates whether tail call optimization will be applied, and an array of parameter expressions. It can be used when the delegate type is not known at compile time. + /// An to set the property equal to. + /// A that indicates if tail call optimization will be applied when compiling the created expression. + /// An array that contains objects to use to populate the collection. + /// A that has the property equal to Lambda and the and properties set to the specified values. public static LambdaExpression Lambda(Expression body, bool tailCall, params ParameterExpression[]? parameters) { return Lambda(body, tailCall, (IEnumerable?)parameters); } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. - /// An that contains objects to use to populate the collection. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a by first constructing a delegate type from the expression body, and an enumerable collection of parameter expressions. It can be used when the delegate type is not known at compile time. + /// An to set the property equal to. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to Lambda and the and properties set to the specified values. public static LambdaExpression Lambda(Expression body, IEnumerable? parameters) { return Lambda(body, null, false, parameters); } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. - /// A that indicates if tail call optimization will be applied when compiling the created expression. - /// An that contains objects to use to populate the collection. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a by first constructing a delegate type from the expression body, a parameter that indicates whether tail call optimization will be applied, and an enumerable collection of parameter expressions. It can be used when the delegate type is not known at compile time. + /// An to set the property equal to. + /// A that indicates if tail call optimization will be applied when compiling the created expression. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to Lambda and the and properties set to the specified values. public static LambdaExpression Lambda(Expression body, bool tailCall, IEnumerable? parameters) { return Lambda(body, null, tailCall, parameters); } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. - /// An array that contains objects to use to populate the collection. - /// A representing the delegate signature for the lambda. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a where the delegate type is known at compile time, with an array of parameter expressions. + /// A that represents a delegate signature for the lambda. + /// An to set the property equal to. + /// An array of objects to use to populate the collection. + /// An object that represents a lambda expression which has the property equal to and the and properties set to the specified values. + /// or is . + /// -or- + /// One or more elements in are . + /// does not represent a delegate type. + /// -or- + /// .Type represents a type that is not assignable to the return type of the delegate type represented by . + /// -or- + /// does not contain the same number of elements as the list of parameters for the delegate type represented by . + /// -or- + /// The property of an element of is not assignable from the type of the corresponding parameter type of the delegate type represented by . + /// The object that is returned from this function is of type . The type is used to represent the returned object because the concrete type of the lambda expression is not known at compile time. + /// The number of parameters for the delegate type represented by must equal the length of . + /// The elements of must be reference equal to the parameter expressions in . + /// The property of the resulting object is equal to . If is , the property of the resulting object is an empty collection. public static LambdaExpression Lambda(Type delegateType, Expression body, params ParameterExpression[]? parameters) { return Lambda(delegateType, body, null, false, parameters); } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. - /// A that indicates if tail call optimization will be applied when compiling the created expression. - /// An array that contains objects to use to populate the collection. - /// A representing the delegate signature for the lambda. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a where the delegate type is known at compile time, with a parameter that indicates whether tail call optimization will be applied, and an array of parameter expressions. + /// A representing the delegate signature for the lambda. + /// An to set the property equal to. + /// A that indicates if tail call optimization will be applied when compiling the created expression. + /// An array that contains objects to use to populate the collection. + /// A that has the property equal to Lambda and the and properties set to the specified values. public static LambdaExpression Lambda(Type delegateType, Expression body, bool tailCall, params ParameterExpression[]? parameters) { return Lambda(delegateType, body, null, tailCall, parameters); } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. - /// An that contains objects to use to populate the collection. - /// A representing the delegate signature for the lambda. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a where the delegate type is known at compile time, with an enumerable collection of parameter expressions. + /// A that represents a delegate signature for the lambda. + /// An to set the property equal to. + /// An that contains objects to use to populate the collection. + /// An object that represents a lambda expression which has the property equal to and the and properties set to the specified values. + /// or is . + /// -or- + /// One or more elements in are . + /// does not represent a delegate type. + /// -or- + /// .Type represents a type that is not assignable to the return type of the delegate type represented by . + /// -or- + /// does not contain the same number of elements as the list of parameters for the delegate type represented by . + /// -or- + /// The property of an element of is not assignable from the type of the corresponding parameter type of the delegate type represented by . + /// The object that is returned from this function is of type . The type is used to represent the returned object because the concrete type of the lambda expression is not known at compile time. + /// The number of parameters for the delegate type represented by must equal the length of . + /// The elements of must be reference equal to the parameter expressions in . + /// The property of the resulting object is equal to . If is , the property of the resulting object is an empty collection. + /// The following example demonstrates how to create an expression that represents a lambda expression that adds 1 to the passed argument. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet42"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet42"::: public static LambdaExpression Lambda(Type delegateType, Expression body, IEnumerable? parameters) { return Lambda(delegateType, body, null, false, parameters); } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. - /// A that indicates if tail call optimization will be applied when compiling the created expression. - /// An that contains objects to use to populate the collection. - /// A representing the delegate signature for the lambda. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a where the delegate type is known at compile time, with a parameter that indicates whether tail call optimization will be applied, and an enumerable collection of parameter expressions. + /// A representing the delegate signature for the lambda. + /// An to set the property equal to. + /// A that indicates if tail call optimization will be applied when compiling the created expression. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to Lambda and the and properties set to the specified values. public static LambdaExpression Lambda(Type delegateType, Expression body, bool tailCall, IEnumerable? parameters) { return Lambda(delegateType, body, null, tailCall, parameters); } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. - /// An that contains objects to use to populate the collection. + /// Creates a by first constructing a delegate type from the expression body, the name for the lambda, and an enumerable collection of parameter expressions. It can be used when the delegate type is not known at compile time. + /// An to set the property equal to. /// The name for the lambda. Used for emitting debug information. - /// A that has the property equal to and the and properties set to the specified values. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to Lambda and the and properties set to the specified values. public static LambdaExpression Lambda(Expression body, string? name, IEnumerable? parameters) { return Lambda(body, name, false, parameters); } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. + /// Creates a by first constructing a delegate type from the expression body, the name for the lambda, a parameter that indicates whether tail call optimization will be applied, and an enumerable collection of parameter expressions. It can be used when the delegate type is not known at compile time. + /// An to set the property equal to. /// The name for the lambda. Used for emitting debug information. - /// A that indicates if tail call optimization will be applied when compiling the created expression. - /// An that contains objects to use to populate the collection. - /// A that has the property equal to and the and properties set to the specified values. + /// A that indicates if tail call optimization will be applied when compiling the created expression. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to Lambda and the and properties set to the specified values. public static LambdaExpression Lambda(Expression body, string? name, bool tailCall, IEnumerable? parameters) { ContractUtils.RequiresNotNull(body, nameof(body)); @@ -871,14 +896,12 @@ public static LambdaExpression Lambda(Expression body, string? name, bool tailCa return CreateLambda(delegateType, body, name, tailCall, parameterList); } - /// - /// Creates a by first constructing a delegate type. - /// - /// An to set the property equal to. - /// An that contains objects to use to populate the collection. + /// Creates a where the delegate type is known at compile time, with the name for the lambda, and an enumerable collection of parameter expressions. + /// A representing the delegate signature for the lambda. + /// An to set the property equal to. /// The name for the lambda. Used for emitting debug information. - /// A representing the delegate signature for the lambda. - /// A that has the property equal to and the and properties set to the specified values. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to Lambda and the and properties set to the specified values. public static LambdaExpression Lambda(Type delegateType, Expression body, string? name, IEnumerable? parameters) { ReadOnlyCollection paramList = parameters.ToReadOnly(); @@ -887,15 +910,13 @@ public static LambdaExpression Lambda(Type delegateType, Expression body, string return CreateLambda(delegateType, body, name, false, paramList); } - /// - /// Creates a by first constructing a delegate type. - /// - /// A representing the delegate signature for the lambda. - /// An to set the property equal to. + /// Creates a where the delegate type is known at compile time, with the name for the lambda, a parameter that indicates whether tail call optimization will be applied, and an enumerable collection of parameter expressions. + /// A representing the delegate signature for the lambda. + /// An to set the property equal to. /// The name for the lambda. Used for emitting debug information. - /// A that indicates if tail call optimization will be applied when compiling the created expression. - /// An that contains objects to use to populate the collection. - /// A that has the property equal to and the and properties set to the specified values. + /// A that indicates if tail call optimization will be applied when compiling the created expression. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to Lambda and the and properties set to the specified values. public static LambdaExpression Lambda(Type delegateType, Expression body, string? name, bool tailCall, IEnumerable? parameters) { ReadOnlyCollection paramList = parameters.ToReadOnly(); @@ -1010,12 +1031,13 @@ private static TryGetFuncActionArgsResult ValidateTryGetFuncActionArgs(Type[]? t return TryGetFuncActionArgsResult.Valid; } - /// - /// Creates a object that represents a generic System.Func delegate type that has specific type arguments. - /// The last type argument specifies the return type of the created delegate. - /// - /// An array of objects that specify the type arguments for the System.Func delegate type. - /// The type of a System.Func delegate that has the specified type arguments. + /// Creates a object that represents a generic System.Func delegate type that has specific type arguments. The last type argument specifies the return type of the created delegate. + /// An array of one to seventeen objects that specify the type arguments for the delegate type. + /// The type of a System.Func delegate that has the specified type arguments. + /// contains fewer than one or more than seventeen elements. + /// is . + /// must contain at least one and at most seventeen elements. + /// As an example, if the elements of represent the types `T1…Tn`, the resulting object represents the constructed delegate type `System.Func<T1,…,Tn>` in C# or `System.Func(Of T1,…,Tn)` in Visual Basic. public static Type GetFuncType(params Type[]? typeArgs) { switch (ValidateTryGetFuncActionArgs(typeArgs)) @@ -1038,13 +1060,10 @@ public static Type GetFuncType(params Type[]? typeArgs) } } - /// - /// Creates a object that represents a generic System.Func delegate type that has specific type arguments. - /// The last type argument specifies the return type of the created delegate. - /// - /// An array of objects that specify the type arguments for the System.Func delegate type. - /// When this method returns, contains the generic System.Func delegate type that has specific type arguments. Contains null if there is no generic System.Func delegate that matches the .This parameter is passed uninitialized. - /// true if generic System.Func delegate type was created for specific ; false otherwise. + /// Creates a object that represents a generic System.Func delegate type that has specific type arguments. The last type argument specifies the return type of the created delegate. + /// An array of Type objects that specify the type arguments for the System.Func delegate type. + /// When this method returns, contains the generic System.Func delegate type that has specific type arguments. Contains null if there is no generic System.Func delegate that matches the . This parameter is passed uninitialized. + /// if generic System.Func delegate type was created for specific ; otherwise, . public static bool TryGetFuncType(Type[] typeArgs, [NotNullWhen(true)] out Type? funcType) { if (ValidateTryGetFuncActionArgs(typeArgs) == TryGetFuncActionArgsResult.Valid) @@ -1056,11 +1075,12 @@ public static bool TryGetFuncType(Type[] typeArgs, [NotNullWhen(true)] out Type? return false; } - /// - /// Creates a object that represents a generic System.Action delegate type that has specific type arguments. - /// - /// An array of objects that specify the type arguments for the System.Action delegate type. - /// The type of a System.Action delegate that has the specified type arguments. + /// Creates a object that represents a generic System.Action delegate type that has specific type arguments. + /// An array of up to sixteen objects that specify the type arguments for the delegate type. + /// The type of a System.Action delegate that has the specified type arguments. + /// contains more than sixteen elements. + /// is . + /// As an example, if the elements of represent the types `T1…Tn`, the resulting object represents the constructed delegate type `System.Action<T1,…,Tn>` in C# or `System.Action(Of T1,…,Tn)` in Visual Basic. public static Type GetActionType(params Type[]? typeArgs) { switch (ValidateTryGetFuncActionArgs(typeArgs)) @@ -1083,12 +1103,10 @@ public static Type GetActionType(params Type[]? typeArgs) } } - /// - /// Creates a object that represents a generic System.Action delegate type that has specific type arguments. - /// - /// An array of objects that specify the type arguments for the System.Action delegate type. - /// When this method returns, contains the generic System.Action delegate type that has specific type arguments. Contains null if there is no generic System.Action delegate that matches the .This parameter is passed uninitialized. - /// true if generic System.Action delegate type was created for specific ; false otherwise. + /// Creates a object that represents a generic System.Action delegate type that has specific type arguments. + /// An array of Type objects that specify the type arguments for the System.Action delegate type. + /// When this method returns, contains the generic System.Action delegate type that has specific type arguments. Contains null if there is no generic System.Action delegate that matches the . This parameter is passed uninitialized. + /// if generic System.Action delegate type was created for specific ; otherwise, . public static bool TryGetActionType(Type[] typeArgs, [NotNullWhen(true)] out Type? actionType) { if (ValidateTryGetFuncActionArgs(typeArgs) == TryGetFuncActionArgsResult.Valid) @@ -1100,16 +1118,11 @@ public static bool TryGetActionType(Type[] typeArgs, [NotNullWhen(true)] out Typ return false; } - /// - /// Gets a object that represents a generic System.Func or System.Action delegate type that has specific type arguments. - /// The last type argument determines the return type of the delegate. If no Func or Action is large enough, it will generate a custom - /// delegate type. - /// - /// An array of objects that specify the type arguments of the delegate type. + /// Gets a object that represents a generic System.Func or System.Action delegate type that has specific type arguments. + /// The type arguments of the delegate. /// The delegate type. - /// - /// As with Func, the last argument is the return type. It can be set - /// to to produce an Action. + /// The last type argument determines the return type of the delegate. If no Func or Action is large enough, it will generate a custom delegate type. + /// As with Func, the last argument is the return type. It can be set to System.Void to produce an Action. public static Type GetDelegateType(params Type[] typeArgs) { ContractUtils.RequiresNotEmpty(typeArgs, nameof(typeArgs)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ListInitExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ListInitExpression.cs index b017dddf8e5c23..3d7906302c8f8a 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ListInitExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ListInitExpression.cs @@ -11,13 +11,12 @@ namespace System.Linq.Expressions { - /// - /// Represents a constructor call that has a collection initializer. - /// - /// - /// Use the factory methods to create a ListInitExpression. - /// The value of the property of a ListInitExpression is ListInit. - /// + /// Represents a constructor call that has a collection initializer. + /// Use the factory methods to create a . + /// The value of the property of a is . + /// The following example creates a that represents the initialization of a new dictionary instance that has two key-value pairs. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet7"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet7"::: [DebuggerTypeProxy(typeof(ListInitExpressionProxy))] public sealed class ListInitExpression : Expression { @@ -27,61 +26,47 @@ internal ListInitExpression(NewExpression newExpression, ReadOnlyCollection - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.ListInit; - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type => NewExpression.Type; - /// - /// Gets a value that indicates whether the expression tree node can be reduced. - /// + /// Gets a value that indicates whether the expression tree node can be reduced. + /// if the node can be reduced; otherwise, . public override bool CanReduce => true; - /// - /// Gets the expression that contains a call to the constructor of a collection type. - /// + /// Gets the expression that contains a call to the constructor of a collection type. + /// A that represents the call to the constructor of a collection type. public NewExpression NewExpression { get; } - /// - /// Gets the element initializers that are used to initialize a collection. - /// + /// Gets the element initializers that are used to initialize a collection. + /// A of objects which represent the elements that are used to initialize the collection. public ReadOnlyCollection Initializers { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitListInit(this); } - /// - /// Reduces the binary expression node to a simpler expression. - /// If CanReduce returns true, this should return a valid expression. - /// This method is allowed to return another node which itself - /// must be reduced. - /// + /// Reduces the binary expression node to a simpler expression. /// The reduced expression. + /// If the `CanReduce` method returns true, this method should return a valid expression. + /// This method is allowed to return another node which itself must be reduced. public override Expression Reduce() { return MemberInitExpression.ReduceListInit(NewExpression, Initializers, keepOnStack: true); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public ListInitExpression Update(NewExpression newExpression, IEnumerable initializers) { if (newExpression == NewExpression && initializers != null) @@ -96,26 +81,57 @@ public ListInitExpression Update(NewExpression newExpression, IEnumerableProvides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a that uses a method named "Add" to add elements to a collection. - /// - /// A to set the property equal to. - /// An array of objects to use to populate the collection. - /// A that has the property equal to and the property set to the specified value. + /// Creates a that uses a method named "Add" to add elements to a collection. + /// A to set the property equal to. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the property set to the specified value. + /// or is . + /// -or- + /// One or more elements of are . + /// .Type does not implement . + /// There is no instance method named "Add" (case insensitive) declared in .Type or its base type. + /// -or- + /// The add method on .Type or its base type does not take exactly one argument. + /// -or- + /// The type represented by the property of the first element of is not assignable to the argument type of the add method on .Type or its base type. + /// -or- + /// More than one argument-compatible method named "Add" (case-insensitive) exists on .Type and/or its base type. + /// The property of must represent a type that implements . + /// In order to use this overload of , .Type or its base type must declare a single method named "Add" (case insensitive) that takes exactly one argument. The type of the argument must be assignable from the type represented by the property of the first element of . + /// The property of the returned contains one element of type for each element of . The property of each element of is a singleton collection that contains the corresponding element of . The property of each element of represents the add method that was discovered on .Type or its base type. + /// The property of the resulting is equal to .Type. [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static ListInitExpression ListInit(NewExpression newExpression, params Expression[] initializers) { return ListInit(newExpression, initializers as IEnumerable); } - /// - /// Creates a that uses a method named "Add" to add elements to a collection. - /// - /// A to set the property equal to. - /// An that contains objects to use to populate the collection. - /// A that has the property equal to and the property set to the specified value. + /// Creates a that uses a method named "Add" to add elements to a collection. + /// A to set the property equal to. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the property set to the specified value. + /// or is . + /// -or- + /// One or more elements of are . + /// .Type does not implement . + /// There is no instance method named "Add" (case insensitive) declared in .Type or its base type. + /// -or- + /// The add method on .Type or its base type does not take exactly one argument. + /// -or- + /// The type represented by the property of the first element of is not assignable to the argument type of the add method on .Type or its base type. + /// -or- + /// More than one argument-compatible method named "Add" (case-insensitive) exists on .Type and/or its base type. + /// The property of must represent a type that implements . + /// In order to use this overload of , .Type or its base type must declare a single method named "Add" (case insensitive) that takes exactly one argument. The type of the argument must be assignable from the type represented by the property of the first element of . + /// The property of the returned contains one element of type for each element of . The property of each element of is a singleton collection that contains the corresponding element of . The property of each element of represents the add method that was discovered on .Type or its base type. + /// The property of the resulting is equal to .Type. [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static ListInitExpression ListInit(NewExpression newExpression, IEnumerable initializers) { @@ -132,26 +148,48 @@ public static ListInitExpression ListInit(NewExpression newExpression, IEnumerab return ListInit(newExpression, addMethod, initializerlist); } - /// - /// Creates a that uses a specified method to add elements to a collection. - /// - /// A to set the property equal to. - /// A that represents an instance method named "Add" (case insensitive), that adds an element to a collection. - /// An array of objects to use to populate the collection. - /// A that has the property equal to and the property set to the specified value. + /// Creates a that uses a specified method to add elements to a collection. + /// A to set the property equal to. + /// A that represents an instance method that takes one argument, that adds an element to a collection. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the property set to the specified value. + /// or is . + /// -or- + /// One or more elements of are . + /// .Type does not implement . + /// -or- + /// is not and it does not represent an instance method named "Add" (case insensitive) that takes exactly one argument. + /// -or- + /// is not and the type represented by the property of one or more elements of is not assignable to the argument type of the method that represents. + /// is and no instance method named "Add" that takes one type-compatible argument exists on .Type or its base type. + /// The property of must represent a type that implements . + /// If is , .Type or its base type must declare a single method named "Add" (case insensitive) that takes exactly one argument. If is not , it must represent an instance method named "Add" (case insensitive) that has exactly one parameter. The type represented by the property of each element of must be assignable to the argument type of the add method. + /// The property of the returned contains one element of type for each element of . The property of each element of is a singleton collection that contains the corresponding element of . The property of each element of is equal to . + /// The property of the resulting is equal to .Type. [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static ListInitExpression ListInit(NewExpression newExpression, MethodInfo? addMethod, params Expression[] initializers) { return ListInit(newExpression, addMethod, initializers as IEnumerable); } - /// - /// Creates a that uses a specified method to add elements to a collection. - /// - /// A to set the property equal to. - /// A that represents an instance method named "Add" (case insensitive), that adds an element to a collection. - /// An that contains objects to use to populate the Initializers collection. - /// A that has the property equal to and the property set to the specified value. + /// Creates a that uses a specified method to add elements to a collection. + /// A to set the property equal to. + /// A that represents an instance method named "Add" (case insensitive), that adds an element to a collection. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the property set to the specified value. + /// or is . + /// -or- + /// One or more elements of are . + /// .Type does not implement . + /// -or- + /// is not and it does not represent an instance method named "Add" (case insensitive) that takes exactly one argument. + /// -or- + /// is not and the type represented by the property of one or more elements of is not assignable to the argument type of the method that represents. + /// is and no instance method named "Add" that takes one type-compatible argument exists on .Type or its base type. + /// The property of must represent a type that implements . + /// If is , .Type or its base type must declare a single method named "Add" (case insensitive) that takes exactly one argument. If is not , it must represent an instance method named "Add" (case insensitive) that has exactly one parameter. The type represented by the property of each element of must be assignable to the argument type of the add method. + /// The property of the returned contains one element of type for each element of . The property of each element of is a singleton collection that contains the corresponding element of . The property of each element of is equal to . + /// The property of the resulting is equal to .Type. [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static ListInitExpression ListInit(NewExpression newExpression, MethodInfo? addMethod, IEnumerable initializers) { @@ -171,34 +209,37 @@ public static ListInitExpression ListInit(NewExpression newExpression, MethodInf return ListInit(newExpression, new TrueReadOnlyCollection(initList)); } - /// - /// Creates a that uses specified objects to initialize a collection. - /// - /// A to set the property equal to. - /// An array that contains objects to use to populate the collection. - /// - /// A that has the property equal to - /// and the and properties set to the specified values. - /// - /// - /// The property of must represent a type that implements . - /// The property of the resulting is equal to .Type. - /// + /// Creates a that uses specified objects to initialize a collection. + /// A to set the property equal to. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// -or- + /// One or more elements of are . + /// .Type does not implement . + /// The property of must represent a type that implements . + /// The property of the resulting is equal to .Type. + /// The following example demonstrates how to use the method to create a that represents the initialization of a new dictionary instance with two key-value pairs. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet7"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet7"::: public static ListInitExpression ListInit(NewExpression newExpression, params ElementInit[] initializers) { return ListInit(newExpression, (IEnumerable)initializers); } - /// - /// Creates a that uses specified objects to initialize a collection. - /// - /// A to set the property equal to. - /// An that contains objects to use to populate the collection. - /// An that contains objects to use to populate the collection. - /// - /// The property of must represent a type that implements . - /// The property of the resulting is equal to .Type. - /// + /// Creates a that uses specified objects to initialize a collection. + /// A to set the property equal to. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// -or- + /// One or more elements of are . + /// .Type does not implement . + /// The property of must represent a type that implements . + /// The property of the resulting is equal to .Type. + /// The following example demonstrates how to use the method to create a that represents the initialization of a new dictionary instance with two key-value pairs. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet7"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet7"::: public static ListInitExpression ListInit(NewExpression newExpression, IEnumerable initializers) { ContractUtils.RequiresNotNull(newExpression, nameof(newExpression)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LoopExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LoopExpression.cs index 3587b940c7ef70..0e85063f05136d 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LoopExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LoopExpression.cs @@ -6,9 +6,11 @@ namespace System.Linq.Expressions { - /// - /// Represents an infinite loop. It can be exited with "break". - /// + /// Represents an infinite loop. It can be exited with "break". + /// + /// The following example demonstrates how to create a block expression that contains a object by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet44"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet44"::: [DebuggerTypeProxy(typeof(LoopExpressionProxy))] public sealed class LoopExpression : Expression { @@ -19,51 +21,39 @@ internal LoopExpression(Expression body, LabelTarget? @break, LabelTarget? @cont ContinueLabel = @continue; } - /// - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type => BreakLabel == null ? typeof(void) : BreakLabel.Type; - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType => ExpressionType.Loop; - /// - /// Gets the that is the body of the loop. - /// + /// Gets the that is the body of the loop. + /// The that is the body of the loop. public Expression Body { get; } - /// - /// Gets the that is used by the loop body as a break statement target. - /// + /// Gets the that is used by the loop body as a break statement target. + /// The that is used by the loop body as a break statement target. public LabelTarget? BreakLabel { get; } - /// - /// Gets the that is used by the loop body as a continue statement target. - /// + /// Gets the that is used by the loop body as a continue statement target. + /// The that is used by the loop body as a continue statement target. public LabelTarget? ContinueLabel { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitLoop(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public LoopExpression Update(LabelTarget? breakLabel, LabelTarget? continueLabel, Expression body) { if (breakLabel == BreakLabel && continueLabel == ContinueLabel && body == Body) @@ -74,36 +64,39 @@ public LoopExpression Update(LabelTarget? breakLabel, LabelTarget? continueLabel } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a with the given body. - /// + /// Creates a with the given body. /// The body of the loop. - /// The created . + /// The created . public static LoopExpression Loop(Expression body) { return Loop(body, @break: null); } - /// - /// Creates a with the given body and break target. - /// + /// Creates a with the given body and break target. /// The body of the loop. /// The break target used by the loop body. - /// The created . + /// The created . + /// + /// The following example demonstrates how to create a block expression that contains a object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet44"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet44"::: public static LoopExpression Loop(Expression body, LabelTarget? @break) { return Loop(body, @break, @continue: null); } - /// - /// Creates a with the given body. - /// + /// Creates a with the given body. /// The body of the loop. /// The break target used by the loop body. /// The continue target used by the loop body. - /// The created . + /// The created . public static LoopExpression Loop(Expression body, LabelTarget? @break, LabelTarget? @continue) { ExpressionUtils.RequiresCanRead(body, nameof(body)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs index 2226b7f5a988cf..a16ed5bd561d19 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberAssignment.cs @@ -7,9 +7,9 @@ namespace System.Linq.Expressions { - /// - /// Represents assignment to a member of an object. - /// + /// Represents assignment operation for a field or property of an object. + /// Use the factory methods to create a . + /// A has the property equal to . public sealed class MemberAssignment : MemberBinding { private readonly Expression _expression; @@ -22,18 +22,13 @@ internal MemberAssignment(MemberInfo member, Expression expression) _expression = expression; } - /// - /// Gets the which represents the object whose member is being assigned to. - /// + /// Gets the expression to assign to the field or property. + /// The that represents the value to assign to the field or property. public Expression Expression => _expression; - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public MemberAssignment Update(Expression expression) { if (expression == Expression) @@ -48,14 +43,24 @@ internal override void ValidateAsDefinedHere(int index) } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a binding the specified value to the given member. - /// - /// The for the member which is being assigned to. - /// The value to be assigned to . - /// The created . + /// Creates a that represents the initialization of a field or property. + /// A to set the property equal to. + /// An to set the property equal to. + /// A that has equal to and the and properties set to the specified values. + /// or is . + /// does not represent a field or property. + /// -or- + /// The property represented by does not have a accessor. + /// -or- + /// .Type is not assignable to the type of the field or property that represents. + /// The property of must be assignable to the type represented by the or property of . public static MemberAssignment Bind(MemberInfo member, Expression expression) { ContractUtils.RequiresNotNull(member, nameof(member)); @@ -69,12 +74,17 @@ public static MemberAssignment Bind(MemberInfo member, Expression expression) return new MemberAssignment(member, expression); } - /// - /// Creates a binding the specified value to the given property. - /// - /// The for the property which is being assigned to. - /// The value to be assigned to . - /// The created . + /// Creates a that represents the initialization of a member by using a property accessor method. + /// A that represents a property accessor method. + /// An to set the property equal to. + /// A that has the property equal to , the property set to the that represents the property accessed in , and the property set to . + /// or is . + /// does not represent a property accessor method. + /// -or- + /// The property accessed by does not have a accessor. + /// -or- + /// .Type is not assignable to the type of the field or property that represents. + /// The property of must be assignable to the type represented by the property of the property accessed in . [RequiresUnreferencedCode(PropertyFromAccessorRequiresUnreferencedCode)] public static MemberAssignment Bind(MethodInfo propertyAccessor, Expression expression) { diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs index 6335cd7f5dc04e..95e8c08d74a090 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberBinding.cs @@ -5,35 +5,23 @@ namespace System.Linq.Expressions { - /// - /// Describes the binding types that are used in MemberInitExpression objects. - /// + /// Describes the binding types that are used in objects. public enum MemberBindingType { - /// - /// A binding that represents initializing a member with the value of an expression. - /// + /// A binding that represents initializing a member with the value of an expression. Assignment, - /// - /// A binding that represents recursively initializing members of a member. - /// + /// A binding that represents recursively initializing members of a member. MemberBinding, - /// - /// A binding that represents initializing a member of type or from a list of elements. - /// + /// A binding that represents initializing a member of type or from a list of elements. ListBinding } - /// - /// Provides the base class from which the classes that represent bindings that are used to initialize members of a newly created object derive. - /// + /// Provides the base class from which the classes that represent bindings that are used to initialize members of a newly created object derive. public abstract class MemberBinding { - /// - /// Initializes an instance of class. - /// - /// The type of member binding. - /// The field or property to be initialized. + /// Initializes a new instance of the class. + /// The that discriminates the type of binding that is represented. + /// The that represents a field or property to be initialized. [Obsolete("Do not use this constructor. It will be removed in future releases.")] protected MemberBinding(MemberBindingType type, MemberInfo member) { @@ -41,20 +29,16 @@ protected MemberBinding(MemberBindingType type, MemberInfo member) Member = member; } - /// - /// Gets the type of binding that is represented. - /// + /// Gets the type of binding that is represented. + /// One of the values. public MemberBindingType BindingType { get; } - /// - /// Gets the field or property to be initialized. - /// + /// Gets the field or property to be initialized. + /// The that represents the field or property to be initialized. public MemberInfo Member { get; } - /// - /// Returns a that represents the current . - /// - /// A that represents the current . + /// Returns a textual representation of the . + /// A textual representation of the . public override string ToString() { return ExpressionStringBuilder.MemberBindingToString(this); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberExpression.cs index 1e9ff0179a5d1a..5113f9abb00375 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberExpression.cs @@ -8,20 +8,21 @@ namespace System.Linq.Expressions { - /// - /// Represents accessing a field or property. - /// + /// Represents accessing a field or property. + /// Use the , or factory methods to create a . + /// The value of the property of a is . + /// The following example creates a that represents getting the value of a field member. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet5"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet5"::: [DebuggerTypeProxy(typeof(MemberExpressionProxy))] public class MemberExpression : Expression { - /// - /// Gets the field or property to be accessed. - /// + /// Gets the field or property to be accessed. + /// The that represents the field or property to be accessed. public MemberInfo Member => GetMember(); - /// - /// Gets the containing object of the field or property. - /// + /// Gets the containing object of the field or property. + /// An that represents the containing object of the field or property. public Expression? Expression { get; } // param order: factories args in order, then other args @@ -48,10 +49,8 @@ internal static MemberExpression Make(Expression? expression, MemberInfo member) return fi == null ? (MemberExpression)Make(expression, (PropertyInfo)member) : Make(expression, fi); } - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.MemberAccess; [ExcludeFromCodeCoverage(Justification = "Unreachable")] @@ -60,21 +59,18 @@ internal virtual MemberInfo GetMember() throw ContractUtils.Unreachable; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitMember(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public MemberExpression Update(Expression? expression) { if (expression == Expression) @@ -114,16 +110,22 @@ public PropertyExpression(Expression? expression, PropertyInfo member) public sealed override Type Type => _property.PropertyType; } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - #region Field - - /// - /// Creates a accessing a field. - /// - /// The containing object of the field. This can be null for static fields. - /// The field to be accessed. - /// The created . + /// Creates a that represents accessing a field. + /// An to set the property equal to. For ( in Visual Basic), must be . + /// The to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// -or- + /// The field represented by is not ( in Visual Basic) and is . + /// .Type is not assignable to the declaring type of the field represented by . + /// The property of the resulting is equal to the property of . public static MemberExpression Field(Expression? expression, FieldInfo field) { ContractUtils.RequiresNotNull(field, nameof(field)); @@ -144,12 +146,17 @@ public static MemberExpression Field(Expression? expression, FieldInfo field) return MemberExpression.Make(expression, field); } - /// - /// Creates a accessing a field. - /// - /// The containing object of the field. This can be null for static fields. - /// The field to be accessed. - /// The created . + /// Creates a that represents accessing a field given the name of the field. + /// An whose contains a field named . This can be null for static fields. + /// The name of a field to be accessed. + /// A that has the property equal to , the property set to , and the property set to the that represents the field denoted by . + /// or is . + /// No field named is defined in .Type or its base types. + /// The property of the resulting is equal to the property of the that represents the field denoted by . + /// This method searches .Type and its base types for a field that has the name . Public fields are given preference over non-public fields. If a matching field is found, this method passes and the that represents that field to . + /// The following code example shows how to create an expression that represents accessing a field. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet37"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet37"::: [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static MemberExpression Field(Expression expression, string fieldName) { @@ -166,13 +173,11 @@ public static MemberExpression Field(Expression expression, string fieldName) return Expression.Field(expression, fi); } - /// - /// Creates a accessing a field. - /// - /// The containing object of the field. This can be null for static fields. - /// The containing the field. + /// Creates a that represents accessing a field. + /// The containing object of the field. This can be null for static fields. + /// The that contains the field. /// The field to be accessed. - /// The created . + /// The created . public static MemberExpression Field( Expression? expression, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] Type type, @@ -192,16 +197,17 @@ public static MemberExpression Field( return Expression.Field(expression, fi); } - #endregion - - #region Property - - /// - /// Creates a accessing a property. - /// - /// The containing object of the property. This can be null for static properties. - /// The property to be accessed. - /// The created . + /// Creates a that represents accessing a property. + /// An whose contains a property named . This can be for static properties. + /// The name of a property to be accessed. + /// A that has the property equal to , the property set to , and the property set to the that represents the property denoted by . + /// or is . + /// No property named is defined in .Type or its base types. + /// The property of the resulting is equal to the property of the that represents the property denoted by . + /// This method searches .Type and its base types for a property that has the name . Public properties are given preference over non-public properties. If a matching property is found, this method passes and the that represents that property to . + /// The following example shows how to create an expression that represents accessing a property. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet38"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet38"::: [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static MemberExpression Property(Expression expression, string propertyName) { @@ -217,13 +223,11 @@ public static MemberExpression Property(Expression expression, string propertyNa return Property(expression, pi); } - /// - /// Creates a accessing a property. - /// - /// The containing object of the property. This can be null for static properties. - /// The containing the property. + /// Creates a accessing a property. + /// The containing object of the property. This can be null for static properties. + /// The that contains the property. /// The property to be accessed. - /// The created . + /// The created . public static MemberExpression Property( Expression? expression, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties| DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, @@ -241,12 +245,16 @@ public static MemberExpression Property( return Property(expression, pi); } - /// - /// Creates a accessing a property. - /// - /// The containing object of the property. This can be null for static properties. - /// The property to be accessed. - /// The created . + /// Creates a that represents accessing a property. + /// An to set the property equal to. This can be null for static properties. + /// The to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// -or- + /// The property that represents is not ( in Visual Basic) and is . + /// .Type is not assignable to the declaring type of the property that represents. + /// The property of the resulting is equal to the property of . + /// If the property represented by is (`Shared` in Visual Basic), can be . public static MemberExpression Property(Expression? expression, PropertyInfo property) { ContractUtils.RequiresNotNull(property, nameof(property)); @@ -290,12 +298,18 @@ public static MemberExpression Property(Expression? expression, PropertyInfo pro return MemberExpression.Make(expression, property); } - /// - /// Creates a accessing a property. - /// - /// The containing object of the property. This can be null for static properties. - /// An accessor method of the property to be accessed. - /// The created . + /// Creates a that represents accessing a property by using a property accessor method. + /// An to set the property equal to. This can be null for static properties. + /// The that represents a property accessor method. + /// A that has the property equal to , the property set to and the property set to the that represents the property accessed in . + /// is . + /// -or- + /// The method that represents is not ( in Visual Basic) and is . + /// .Type is not assignable to the declaring type of the method represented by . + /// -or- + /// The method that represents is not a property accessor method. + /// The property of the resulting is equal to the property of . + /// If the method represented by is (`Shared` in Visual Basic), can be . [RequiresUnreferencedCode(PropertyFromAccessorRequiresUnreferencedCode)] public static MemberExpression Property(Expression? expression, MethodInfo propertyAccessor) { @@ -348,14 +362,17 @@ private static bool CheckMethod(MethodInfo method, MethodInfo propertyMethod) return false; } - #endregion - - /// - /// Creates a accessing a property or field. - /// - /// The containing object of the member. This can be null for static members. - /// The member to be accessed. - /// The created . + /// Creates a that represents accessing a property or field. + /// An whose contains a property or field named . + /// The name of a property or field to be accessed. + /// A that has the property equal to , the property set to , and the property set to the or that represents the property or field denoted by . + /// or is . + /// No property or field named is defined in .Type or its base types. + /// The property of the resulting is equal to the or properties of the or , respectively, that represents the property or field denoted by . + /// This method searches .Type and its base types for an instance property or field that has the name . Static properties or fields are not supported. Public properties and fields are given preference over non-public properties and fields. Also, properties are given preference over fields. If a matching property or field is found, this method passes and the or that represents that property or field to or , respectively. + /// The following example shows how to create an expression that represents accessing a property or field. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet39"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet39"::: [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static MemberExpression PropertyOrField(Expression expression, string propertyOrFieldName) { @@ -377,12 +394,13 @@ public static MemberExpression PropertyOrField(Expression expression, string pro throw Error.NotAMemberOfType(propertyOrFieldName, expression.Type, nameof(propertyOrFieldName)); } - /// - /// Creates a accessing a property or field. - /// - /// The containing object of the member. This can be null for static members. - /// The member to be accessed. - /// The created . + /// Creates a that represents accessing either a field or a property. + /// An that represents the object that the member belongs to. This can be null for static members. + /// The that describes the field or property to be accessed. + /// The that results from calling the appropriate factory method. + /// is . + /// does not represent a field or property. + /// This method can be used to create a that represents accessing either a field or a property, depending on the type of . If is of type , this method calls to create the . If is of type , this method calls to create the . public static MemberExpression MakeMemberAccess(Expression? expression, MemberInfo member) { ContractUtils.RequiresNotNull(member, nameof(member)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberInitExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberInitExpression.cs index 9785b5d2844cbd..150d79b74467a7 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberInitExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberInitExpression.cs @@ -8,9 +8,12 @@ namespace System.Linq.Expressions { - /// - /// Represents calling a constructor and initializing one or more members of the new object. - /// + /// Represents calling a constructor and initializing one or more members of the new object. + /// Use the factory methods to create a . + /// The value of the property of a is . + /// The following example creates a that represents the initialization of two members of a new object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet9"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet9"::: [DebuggerTypeProxy(typeof(MemberInitExpressionProxy))] public sealed class MemberInitExpression : Expression { @@ -20,47 +23,38 @@ internal MemberInitExpression(NewExpression newExpression, ReadOnlyCollection - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type => NewExpression.Type; - /// - /// Gets a value that indicates whether the expression tree node can be reduced. - /// + /// Gets a value that indicates whether the expression tree node can be reduced. + /// if the node can be reduced; otherwise, . public override bool CanReduce => true; - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this Expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType => ExpressionType.MemberInit; /// Gets the expression that represents the constructor call. - /// A that represents the constructor call. + /// A that represents the constructor call. public NewExpression NewExpression { get; } /// Gets the bindings that describe how to initialize the members of the newly created object. - /// A of objects which describe how to initialize the members. + /// A of objects which describe how to initialize the members. public ReadOnlyCollection Bindings { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitMemberInit(this); } - /// - /// Reduces the to a simpler expression. - /// If CanReduce returns true, this should return a valid expression. - /// This method is allowed to return another node which itself - /// must be reduced. - /// + /// Reduces the to a simpler expression. /// The reduced expression. + /// If the `CanReduce` method returns true, this method should return a valid expression. + /// This method is allowed to return another node which itself must be reduced. public override Expression Reduce() { return ReduceMemberInit(NewExpression, Bindings, keepOnStack: true); @@ -111,14 +105,10 @@ internal static Expression ReduceMemberBinding(ParameterExpression objVar, Membe }; } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public MemberInitExpression Update(NewExpression newExpression, IEnumerable bindings) { if (newExpression == NewExpression && bindings != null) @@ -133,27 +123,38 @@ public MemberInitExpression Update(NewExpression newExpression, IEnumerableProvides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// Creates a . - /// A that has the property equal to and the and properties set to the specified values. - /// A to set the property equal to. - /// An array of objects to use to populate the collection. - /// - /// or is null. - /// The property of an element of does not represent a member of the type that .Type represents. + /// Creates a . + /// A to set the property equal to. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The property of an element of does not represent a member of the type that .Type represents. + /// The property of the resulting is equal to the property of . + /// The following example demonstrates how to use the method to create a that represents the initialization of two members of a new object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet9"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet9"::: public static MemberInitExpression MemberInit(NewExpression newExpression, params MemberBinding[] bindings) { return MemberInit(newExpression, (IEnumerable)bindings); } - /// Creates a . - /// A that has the property equal to and the and properties set to the specified values. - /// A to set the property equal to. - /// An that contains objects to use to populate the collection. - /// - /// or is null. - /// The property of an element of does not represent a member of the type that .Type represents. + /// Represents an expression that creates a new object and initializes a property of the object. + /// A to set the property equal to. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The property of an element of does not represent a member of the type that .Type represents. + /// The property of the resulting is equal to the property of . + /// The following example demonstrates an expression that creates a new object and initializes a property of the object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet40"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet40"::: public static MemberInitExpression MemberInit(NewExpression newExpression, IEnumerable bindings) { ContractUtils.RequiresNotNull(newExpression, nameof(newExpression)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberListBinding.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberListBinding.cs index fbf4bb8ac97fc2..75b9e7b6b4dec3 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberListBinding.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberListBinding.cs @@ -11,9 +11,9 @@ namespace System.Linq.Expressions { - /// - /// Represents initializing the elements of a collection member of a newly created object. - /// + /// Represents initializing the elements of a collection member of a newly created object. + /// Use the factory methods to create a . + /// A has the property equal to . public sealed class MemberListBinding : MemberBinding { internal MemberListBinding(MemberInfo member, ReadOnlyCollection initializers) @@ -24,18 +24,13 @@ internal MemberListBinding(MemberInfo member, ReadOnlyCollection in Initializers = initializers; } - /// - /// Gets the element initializers for initializing a collection member of a newly created object. - /// + /// Gets the element initializers for initializing a collection member of a newly created object. + /// A of objects to initialize a collection member with. public ReadOnlyCollection Initializers { get; } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public MemberListBinding Update(IEnumerable initializers) { if (initializers != null) @@ -54,29 +49,38 @@ internal override void ValidateAsDefinedHere(int index) } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// Creates a where the member is a field or property. - /// A that has the property equal to and the and properties set to the specified values. - /// A that represents a field or property to set the property equal to. - /// An array of objects to use to populate the collection. - /// - /// is null. -or-One or more elements of is null. - /// - /// does not represent a field or property.-or-The or of the field or property that represents does not implement . + /// Creates a where the member is a field or property. + /// A that represents a field or property to set the property equal to. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// -or- + /// One or more elements of are . + /// does not represent a field or property. + /// -or- + /// The or of the field or property that represents does not implement . public static MemberListBinding ListBind(MemberInfo member, params ElementInit[] initializers) { return ListBind(member, (IEnumerable)initializers); } - /// Creates a where the member is a field or property. - /// A that has the property equal to and the and properties set to the specified values. - /// A that represents a field or property to set the property equal to. - /// An that contains objects to use to populate the collection. - /// - /// is null. -or-One or more elements of is null. - /// - /// does not represent a field or property.-or-The or of the field or property that represents does not implement . + /// Creates a where the member is a field or property. + /// A that represents a field or property to set the property equal to. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// -or- + /// One or more elements of are . + /// does not represent a field or property. + /// -or- + /// The or of the field or property that represents does not implement . public static MemberListBinding ListBind(MemberInfo member, IEnumerable initializers) { ContractUtils.RequiresNotNull(member, nameof(member)); @@ -88,28 +92,32 @@ public static MemberListBinding ListBind(MemberInfo member, IEnumerableCreates a object based on a specified property accessor method. - /// A that has the property equal to , the property set to the that represents the property accessed in , and populated with the elements of . - /// A that represents a property accessor method. - /// An array of objects to use to populate the collection. - /// - /// is null. -or-One or more elements of is null. - /// - /// does not represent a property accessor method.-or-The of the property that the method represented by accesses does not implement . + /// Creates a object based on a specified property accessor method. + /// A that represents a property accessor method. + /// An array of objects to use to populate the collection. + /// A that has the property equal to , the property set to the that represents the property accessed in , and populated with the elements of . + /// is . + /// -or- + /// One or more elements of are . + /// does not represent a property accessor method. + /// -or- + /// The of the property that the method represented by accesses does not implement . [RequiresUnreferencedCode(PropertyFromAccessorRequiresUnreferencedCode)] public static MemberListBinding ListBind(MethodInfo propertyAccessor, params ElementInit[] initializers) { return ListBind(propertyAccessor, (IEnumerable)initializers); } - /// Creates a based on a specified property accessor method. - /// A that has the property equal to , the property set to the that represents the property accessed in , and populated with the elements of . - /// A that represents a property accessor method. - /// An that contains objects to use to populate the collection. - /// - /// is null. -or-One or more elements of are null. - /// - /// does not represent a property accessor method.-or-The of the property that the method represented by accesses does not implement . + /// Creates a based on a specified property accessor method. + /// A that represents a property accessor method. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to , the property set to the that represents the property accessed in , and populated with the elements of . + /// is . + /// -or- + /// One or more elements of are . + /// does not represent a property accessor method. + /// -or- + /// The of the property that the method represented by accesses does not implement . [RequiresUnreferencedCode(PropertyFromAccessorRequiresUnreferencedCode)] public static MemberListBinding ListBind(MethodInfo propertyAccessor, IEnumerable initializers) { diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs index 54a90a7fa59454..fcd984f1c522e2 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MemberMemberBinding.cs @@ -10,13 +10,9 @@ namespace System.Linq.Expressions { - /// - /// Represents initializing members of a member of a newly created object. - /// - /// - /// Use the factory methods to create a . - /// The value of the property of a object is . - /// + /// Represents initializing members of a member of a newly created object. + /// Use the factory methods to create a . + /// The value of the property of a object is . public sealed class MemberMemberBinding : MemberBinding { internal MemberMemberBinding(MemberInfo member, ReadOnlyCollection bindings) @@ -27,18 +23,13 @@ internal MemberMemberBinding(MemberInfo member, ReadOnlyCollection - /// Gets the bindings that describe how to initialize the members of a member. - /// + /// Gets the bindings that describe how to initialize the members of a member. + /// A of objects that describe how to initialize the members of the member. public ReadOnlyCollection Bindings { get; } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public MemberMemberBinding Update(IEnumerable bindings) { if (bindings != null) @@ -57,25 +48,36 @@ internal override void ValidateAsDefinedHere(int index) } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a that represents the recursive initialization of members of a field or property. - /// - /// The to set the property equal to. - /// An array of objects to use to populate the collection. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a that represents the recursive initialization of members of a field or property. + /// The to set the property equal to. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// does not represent a field or property. + /// -or- + /// The property of an element of does not represent a member of the type of the field or property that represents. + /// The parameter must represent a field or property. public static MemberMemberBinding MemberBind(MemberInfo member, params MemberBinding[] bindings) { return MemberBind(member, (IEnumerable)bindings); } - /// - /// Creates a that represents the recursive initialization of members of a field or property. - /// - /// The to set the property equal to. - /// An that contains objects to use to populate the collection. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a that represents the recursive initialization of members of a field or property. + /// The to set the property equal to. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// does not represent a field or property. + /// -or- + /// The property of an element of does not represent a member of the type of the field or property that represents. + /// The parameter must represent a field or property. public static MemberMemberBinding MemberBind(MemberInfo member, IEnumerable bindings) { ContractUtils.RequiresNotNull(member, nameof(member)); @@ -87,32 +89,28 @@ public static MemberMemberBinding MemberBind(MemberInfo member, IEnumerable - /// Creates a that represents the recursive initialization of members of a member that is accessed by using a property accessor method. - /// - /// The that represents a property accessor method. - /// An that contains objects to use to populate the collection. - /// - /// A that has the property equal to , - /// the Member property set to the that represents the property accessed in , - /// and properties set to the specified values. - /// + /// Creates a that represents the recursive initialization of members of a member that is accessed by using a property accessor method. + /// The that represents a property accessor method. + /// An array of objects to use to populate the collection. + /// A that has the property equal to , the property set to the that represents the property accessed in , and properties set to the specified values. + /// or is . + /// does not represent a property accessor method. + /// -or- + /// The property of an element of does not represent a member of the type of the property accessed by the method that represents. [RequiresUnreferencedCode(PropertyFromAccessorRequiresUnreferencedCode)] public static MemberMemberBinding MemberBind(MethodInfo propertyAccessor, params MemberBinding[] bindings) { return MemberBind(propertyAccessor, (IEnumerable)bindings); } - /// - /// Creates a that represents the recursive initialization of members of a member that is accessed by using a property accessor method. - /// - /// The that represents a property accessor method. - /// An that contains objects to use to populate the collection. - /// - /// A that has the property equal to , - /// the Member property set to the that represents the property accessed in , - /// and properties set to the specified values. - /// + /// Creates a that represents the recursive initialization of members of a member that is accessed by using a property accessor method. + /// The that represents a property accessor method. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to , the property set to the that represents the property accessed in , and properties set to the specified values. + /// or is . + /// does not represent a property accessor method. + /// -or- + /// The property of an element of does not represent a member of the type of the property accessed by the method that represents. [RequiresUnreferencedCode(PropertyFromAccessorRequiresUnreferencedCode)] public static MemberMemberBinding MemberBind(MethodInfo propertyAccessor, IEnumerable bindings) { diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs index d918fd90a382e6..17a3adfa65b864 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs @@ -10,9 +10,12 @@ namespace System.Linq.Expressions { - /// - /// Represents a call to either static or an instance method. - /// + /// Represents a call to either static or an instance method. + /// Use the , , or factory method to create a . + /// The value of the property of a object is . + /// The following example creates a object that represents indexing into a two-dimensional array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet3"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet3"::: [DebuggerTypeProxy(typeof(MethodCallExpressionProxy))] public class MethodCallExpression : Expression, IArgumentProvider { @@ -23,42 +26,31 @@ internal MethodCallExpression(MethodInfo method) internal virtual Expression? GetInstance() => null; - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.Call; - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type => Method.ReturnType; - /// - /// Gets the for the method to be called. - /// + /// Gets the for the method to be called. + /// The that represents the called method. public MethodInfo Method { get; } - /// - /// Gets the that represents the instance - /// for instance method calls or null for static method calls. - /// + /// Gets the that represents the instance for instance method calls or null for static method calls. + /// An that represents the receiving object of the method. + /// If a object's property represents a (`Shared` in Visual Basic) method, the property is . public Expression? Object => GetInstance(); - /// - /// Gets a collection of expressions that represent arguments to the method call. - /// + /// Gets a collection of expressions that represent arguments of the called method. + /// A of objects which represent the arguments to the called method. public ReadOnlyCollection Arguments => GetOrMakeArguments(); - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public MethodCallExpression Update(Expression? @object, IEnumerable? arguments) { if (@object == Object) @@ -100,9 +92,10 @@ internal virtual ReadOnlyCollection GetOrMakeArguments() throw ContractUtils.Unreachable; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitMethodCall(this); @@ -828,6 +821,11 @@ internal override MethodCallExpression Rewrite(Expression instance, IReadOnlyLis #endregion + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { #region Call @@ -850,12 +848,15 @@ internal static MethodCallExpression Call(MethodInfo method) return new MethodCallExpression0(method); } - /// Creates a that represents a call to a static method that takes one argument. - /// A that has the property equal to and the and properties set to the specified values. - /// A to set the property equal to. - /// The that represents the first argument. - /// - /// is null. + /// Creates a that represents a call to a ( in Visual Basic) method that takes one argument. + /// A to set the property equal to. + /// The that represents the first argument. + /// A that has the property equal to and the and properties set to the specified values. + /// is null. + /// + /// The following example demonstrates how to create an expression that calls a (`Shared` in Visual Basic) method that takes one argument. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet16"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet16"::: public static MethodCallExpression Call(MethodInfo method, Expression arg0) { ContractUtils.RequiresNotNull(method, nameof(method)); @@ -870,13 +871,12 @@ public static MethodCallExpression Call(MethodInfo method, Expression arg0) return new MethodCallExpression1(method, arg0); } - /// Creates a that represents a call to a static method that takes two arguments. - /// A that has the property equal to and the and properties set to the specified values. - /// A to set the property equal to. - /// The that represents the first argument. - /// The that represents the second argument. - /// - /// is null. + /// Creates a that represents a call to a static method that takes two arguments. + /// A to set the property equal to. + /// The that represents the first argument. + /// The that represents the second argument. + /// A that has the property equal to and the and properties set to the specified values. + /// is null. public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expression arg1) { ContractUtils.RequiresNotNull(method, nameof(method)); @@ -893,14 +893,13 @@ public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expr return new MethodCallExpression2(method, arg0, arg1); } - /// Creates a that represents a call to a static method that takes three arguments. - /// A that has the property equal to and the and properties set to the specified values. - /// A to set the property equal to. - /// The that represents the first argument. - /// The that represents the second argument. - /// The that represents the third argument. - /// - /// is null. + /// Creates a that represents a call to a static method that takes three arguments. + /// A to set the property equal to. + /// The that represents the first argument. + /// The that represents the second argument. + /// The that represents the third argument. + /// A that has the property equal to and the and properties set to the specified values. + /// is null. public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expression arg1, Expression arg2) { ContractUtils.RequiresNotNull(method, nameof(method)); @@ -919,15 +918,14 @@ public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expr return new MethodCallExpression3(method, arg0, arg1, arg2); } - /// Creates a that represents a call to a static method that takes four arguments. - /// A that has the property equal to and the and properties set to the specified values. - /// A to set the property equal to. - /// The that represents the first argument. - /// The that represents the second argument. - /// The that represents the third argument. - /// The that represents the fourth argument. - /// - /// is null. + /// Creates a that represents a call to a static method that takes four arguments. + /// A to set the property equal to. + /// The that represents the first argument. + /// The that represents the second argument. + /// The that represents the third argument. + /// The that represents the fourth argument. + /// A that has the property equal to and the and properties set to the specified values. + /// is null. public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expression arg1, Expression arg2, Expression arg3) { ContractUtils.RequiresNotNull(method, nameof(method)); @@ -948,17 +946,15 @@ public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expr return new MethodCallExpression4(method, arg0, arg1, arg2, arg3); } - /// Creates a that represents a call to a static method that takes five arguments. - /// A that has the property equal to and the and properties set to the specified values. - /// A to set the property equal to. - /// The that represents the first argument. - /// The that represents the second argument. - /// The that represents the third argument. - /// The that represents the fourth argument. - /// The that represents the fifth argument. - /// - /// is null. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a that represents a call to a static method that takes five arguments. + /// A to set the property equal to. + /// The that represents the first argument. + /// The that represents the second argument. + /// The that represents the third argument. + /// The that represents the fourth argument. + /// The that represents the fifth argument. + /// A that has the property equal to and the and properties set to the specified values. + /// is null. public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4) { ContractUtils.RequiresNotNull(method, nameof(method)); @@ -981,34 +977,49 @@ public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expr return new MethodCallExpression5(method, arg0, arg1, arg2, arg3, arg4); } - /// - /// Creates a that represents a call to a static (Shared in Visual Basic) method. - /// - /// The that represents the target method. - /// The array of one or more of that represents the call arguments. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a that represents a call to a ( in Visual Basic) method that has arguments. + /// A that represents a ( in Visual Basic) method to set the property equal to. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// The number of elements in does not equal the number of parameters for the method represented by . + /// -or- + /// One or more of the elements of is not assignable to the corresponding parameter for the method represented by . + /// If is not , it must have the same number of elements as the number of parameters for the method represented by . Each element in must not be and must be assignable to the corresponding parameter of , possibly after *quoting*. + /// [!NOTE] + /// > An element will be quoted only if the corresponding method parameter is of type . Quoting means the element is wrapped in a node. The resulting node is a whose property is the element of `arguments`. + /// ]]> + /// The property of the resulting is empty if is . Otherwise, it contains the same elements as , some of which may be quoted. + /// The property of the resulting is equal to the return type of the method represented by . The property is . public static MethodCallExpression Call(MethodInfo method, params Expression[]? arguments) { return Call(null, method, arguments); } - /// - /// Creates a that represents a call to a static (Shared in Visual Basic) method. - /// - /// The that represents the target method. - /// A collection of that represents the call arguments. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a that represents a call to a static (Shared in Visual Basic) method. + /// The that represents the target method. + /// A collection of that represents the call arguments. + /// A that has the property equal to and the and properties set to the specified values. public static MethodCallExpression Call(MethodInfo method, IEnumerable? arguments) { return Call(null, method, arguments); } - /// - /// Creates a that represents a call to a method that takes no arguments. - /// - /// An that specifies the instance for an instance call. (pass null for a static (Shared in Visual Basic) method). - /// The that represents the target method. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a that represents a call to a method that takes no arguments. + /// An that specifies the instance for an instance method call (pass for a ( in Visual Basic) method). + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// -or- + /// is and represents an instance method. + /// .Type is not assignable to the declaring type of the method represented by . + /// To represent a call to a (`Shared` in Visual Basic) method, pass in for the parameter when you call this method. + /// If represents an instance method, the property of must be assignable to the declaring type of the method represented by . + /// The property of the resulting is empty. The property is equal to the return type of the method represented by . + /// The following code example shows how to create an expression that calls a method without arguments. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet15"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet15"::: public static MethodCallExpression Call(Expression? instance, MethodInfo method) { ContractUtils.RequiresNotNull(method, nameof(method)); @@ -1025,13 +1036,30 @@ public static MethodCallExpression Call(Expression? instance, MethodInfo method) return new MethodCallExpression0(method); } - /// - /// Creates a that represents a method call. - /// - /// An that specifies the instance for an instance call. (pass null for a static (Shared in Visual Basic) method). - /// The that represents the target method. - /// An array of one or more of that represents the call arguments. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a that represents a call to a method that takes arguments. + /// An that specifies the instance for an instance method call (pass for a ( in Visual Basic) method). + /// A to set the property equal to. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the , , and properties set to the specified values. + /// is . + /// -or- + /// is and represents an instance method. + /// -or- + /// is not and one or more of its elements is . + /// .Type is not assignable to the declaring type of the method represented by . + /// -or- + /// The number of elements in does not equal the number of parameters for the method represented by . + /// -or- + /// One or more of the elements of is not assignable to the corresponding parameter for the method represented by . + /// To represent a call to a (`Shared` in Visual Basic) method, pass in for the parameter when you call this method, or call instead. + /// If represents an instance method, the property of must be assignable to the declaring type of the method represented by . + /// If is not , it must have the same number of elements as the number of parameters for the method represented by . Each element in must not be and must be assignable to the corresponding parameter of , possibly after *quoting*. + /// [!NOTE] + /// > An element will be quoted only if the corresponding method parameter is of type . Quoting means the element is wrapped in a node. The resulting node is a whose property is the element of `arguments`. + /// ]]> + /// The property of the resulting is empty if is . Otherwise, it contains the same elements as , some of which may be quoted. + /// The property of the resulting is equal to the return type of the method represented by . public static MethodCallExpression Call(Expression? instance, MethodInfo method, params Expression[]? arguments) { return Call(instance, method, (IEnumerable?)arguments); @@ -1065,14 +1093,16 @@ internal static MethodCallExpression Call(Expression? instance, MethodInfo metho return new MethodCallExpression1(method, arg0); } - /// - /// Creates a that represents a call to a method that takes two arguments. - /// - /// An that specifies the instance for an instance call. (pass null for a static (Shared in Visual Basic) method). - /// The that represents the target method. - /// The that represents the first argument. - /// The that represents the second argument. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a that represents a call to a method that takes two arguments. + /// An that specifies the instance for an instance call. (pass null for a static (Shared in Visual Basic) method). + /// The that represents the target method. + /// The that represents the first argument. + /// The that represents the second argument. + /// A that has the property equal to and the and properties set to the specified values. + /// + /// The following code example shows how to create an expression that calls an instance method that has two arguments. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet17"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet17"::: public static MethodCallExpression Call(Expression? instance, MethodInfo method, Expression arg0, Expression arg1) { ContractUtils.RequiresNotNull(method, nameof(method)); @@ -1094,15 +1124,13 @@ public static MethodCallExpression Call(Expression? instance, MethodInfo method, return new MethodCallExpression2(method, arg0, arg1); } - /// - /// Creates a that represents a call to a method that takes three arguments. - /// - /// An that specifies the instance for an instance call. (pass null for a static (Shared in Visual Basic) method). - /// The that represents the target method. - /// The that represents the first argument. - /// The that represents the second argument. - /// The that represents the third argument. - /// A that has the property equal to and the and properties set to the specified values. + /// Creates a that represents a call to a method that takes three arguments. + /// An that specifies the instance for an instance call. (pass null for a static (Shared in Visual Basic) method). + /// The that represents the target method. + /// The that represents the first argument. + /// The that represents the second argument. + /// The that represents the third argument. + /// A that has the property equal to and the and properties set to the specified values. public static MethodCallExpression Call(Expression? instance, MethodInfo method, Expression arg0, Expression arg1, Expression arg2) { ContractUtils.RequiresNotNull(method, nameof(method)); @@ -1125,18 +1153,17 @@ public static MethodCallExpression Call(Expression? instance, MethodInfo method, return new MethodCallExpression3(method, arg0, arg1, arg2); } - /// Creates a that represents a call to an instance method by calling the appropriate factory method. - /// A that has the property equal to , the property equal to , set to the that represents the specified instance method, and set to the specified arguments. - /// An whose property value will be searched for a specific method. + /// Creates a that represents a call to a method by calling the appropriate factory method. + /// An whose property value will be searched for a specific method. /// The name of the method. - /// - ///An array of objects that specify the type parameters of the generic method. - ///This argument should be null when specifies a non-generic method. - /// - /// An array of objects that represents the arguments to the method. - /// - /// or is null. - /// No method whose name is , whose type parameters match , and whose parameter types match is found in .Type or its base types.-or-More than one method whose name is , whose type parameters match , and whose parameter types match is found in .Type or its base types. + /// An array of objects that specify the type parameters of the generic method. This argument should be null when methodName specifies a non-generic method. + /// An array of objects that represents the arguments to the method. + /// A that has the property equal to , the property equal to , set to the that represents the specified instance method, and set to the specified arguments. + /// or is . + /// No method whose name is , whose type parameters match , and whose parameter types match is found in .Type or its base types. + /// -or- + /// More than one method whose name is , whose type parameters match , and whose parameter types match is found in .Type or its base types. + /// The property of the resulting is equal to the return type of the method denoted by . [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static MethodCallExpression Call(Expression instance, string methodName, Type[]? typeArguments, params Expression[]? arguments) { @@ -1151,18 +1178,17 @@ public static MethodCallExpression Call(Expression instance, string methodName, return Expression.Call(instance, FindMethod(instance.Type, methodName, typeArguments, arguments, flags)!, arguments); } - /// Creates a that represents a call to a static (Shared in Visual Basic) method by calling the appropriate factory method. - /// A that has the property equal to , the property set to the that represents the specified static (Shared in Visual Basic) method, and the property set to the specified arguments. - /// The that specifies the type that contains the specified static (Shared in Visual Basic) method. + /// Creates a that represents a call to a ( in Visual Basic) method by calling the appropriate factory method. + /// The type that contains the specified ( in Visual Basic) method. /// The name of the method. - /// - ///An array of objects that specify the type parameters of the generic method. - ///This argument should be null when specifies a non-generic method. - /// - /// An array of objects that represent the arguments to the method. - /// - /// or is null. - /// No method whose name is , whose type parameters match , and whose parameter types match is found in or its base types.-or-More than one method whose name is , whose type parameters match , and whose parameter types match is found in or its base types. + /// An array of objects that specify the type parameters of the generic method. This argument should be null when methodName specifies a non-generic method. + /// An array of objects that represent the arguments to the method. + /// A that has the property equal to , the property set to the that represents the specified ( in Visual Basic) method, and the property set to the specified arguments. + /// or is . + /// No method whose name is , whose type parameters match , and whose parameter types match is found in or its base types. + /// -or- + /// More than one method whose name is , whose type parameters match , and whose parameter types match is found in or its base types. + /// The property of the resulting is equal to the return type of the method denoted by . The property is . [RequiresUnreferencedCode(GenericMethodRequiresUnreferencedCode)] public static MethodCallExpression Call( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type type, @@ -1178,15 +1204,28 @@ public static MethodCallExpression Call( return Expression.Call(null, FindMethod(type, methodName, typeArguments, arguments, flags)!, arguments); } - /// Creates a that represents a method call. - /// A that has the property equal to and the , , and properties set to the specified values. - /// An to set the property equal to (pass null for a static (Shared in Visual Basic) method). - /// A to set the property equal to. - /// An that contains objects to use to populate the collection. - /// - /// is null.-or- is null and represents an instance method. - /// - /// .Type is not assignable to the declaring type of the method represented by .-or-The number of elements in does not equal the number of parameters for the method represented by .-or-One or more of the elements of is not assignable to the corresponding parameter for the method represented by . + /// Creates a that represents a call to a method that takes arguments. + /// An to set the property equal to (pass for a ( in Visual Basic) method). + /// A to set the property equal to. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the , , and properties set to the specified values. + /// is . + /// -or- + /// is and represents an instance method. + /// .Type is not assignable to the declaring type of the method represented by . + /// -or- + /// The number of elements in does not equal the number of parameters for the method represented by . + /// -or- + /// One or more of the elements of is not assignable to the corresponding parameter for the method represented by . + /// To represent a call to a (`Shared` in Visual Basic) method, pass in for the parameter when you call this method, or call instead. + /// If represents an instance method, the property of must be assignable to the declaring type of the method represented by . + /// If is not , it must have the same number of elements as the number of parameters for the method represented by . Each element in must not be and must be assignable to the corresponding parameter of , possibly after *quoting*. + /// [!NOTE] + /// > An element will be quoted only if the corresponding method parameter is of type . Quoting means the element is wrapped in a node. The resulting node is a whose property is the element of `arguments`. + /// ]]> + /// The property of the resulting is empty if is . Otherwise, it contains the same elements as , some of which may be quoted. + /// The property of the resulting is equal to the return type of the method represented by . public static MethodCallExpression Call(Expression? instance, MethodInfo method, IEnumerable? arguments) { IReadOnlyList argumentList = arguments as IReadOnlyList ?? arguments.ToReadOnly(); @@ -1384,27 +1423,43 @@ private static bool IsCompatible(MethodBase m, Expression[] arguments) return null; } - #endregion - - #region ArrayIndex - - /// Creates a that represents applying an array index operator to a multi-dimensional array. - /// A that has the property equal to and the and properties set to the specified values. - /// An array of instances - indexes for the array index operation. - /// An array that contains objects to use to populate the collection. + /// Creates a that represents applying an array index operator to a multidimensional array. + /// An array of instances - indexes for the array index operation. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// .Type does not represent an array type. + /// -or- + /// The rank of .Type does not match the number of elements in . + /// -or- + /// The property of one or more elements of does not represent the type. + /// Each element of must have equal to . The property of must represent an array type whose rank matches the number of elements in . + /// If the rank of .Type is 1, this method returns a . The property is set to and the property is set to the single element of . The property of the represents the element type of .Type. + /// If the rank of .Type is more than one, this method returns a . The property is set to the that describes the public instance method `Get` on the type represented by the property of . + /// The following example demonstrates how to use the method to create a that represents indexing into a two-dimensional array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet3"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet3"::: public static MethodCallExpression ArrayIndex(Expression array, params Expression[] indexes) { return ArrayIndex(array, (IEnumerable)indexes); } - /// Creates a that represents applying an array index operator to an array of rank more than one. - /// A that has the property equal to and the and properties set to the specified values. - /// An to set the property equal to. - /// An that contains objects to use to populate the collection. - /// - /// or is null. - /// - /// .Type does not represent an array type.-or-The rank of .Type does not match the number of elements in .-or-The property of one or more elements of does not represent the type. + /// Creates a that represents applying an array index operator to an array of rank more than one. + /// An to set the property equal to. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// .Type does not represent an array type. + /// -or- + /// The rank of .Type does not match the number of elements in . + /// -or- + /// The property of one or more elements of does not represent the type. + /// Each element of must have equal to . The property of must represent an array type whose rank matches the number of elements in . + /// If the rank of .Type is 1, this method returns a . The property is set to and the property is set to the single element of . The property of the represents the element type of .Type. + /// If the rank of .Type is more than one, this method returns a . The property is set to the that describes the public instance method `Get` on the type represented by the property of . + /// The following example demonstrates how to use the method to create a that represents indexing into a two-dimensional array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet3"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet3"::: public static MethodCallExpression ArrayIndex(Expression array, IEnumerable indexes) { ExpressionUtils.RequiresCanRead(array, nameof(array), -1); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/NewArrayExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/NewArrayExpression.cs index e3e3b882d1308e..84ea0797e536ed 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/NewArrayExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/NewArrayExpression.cs @@ -9,9 +9,18 @@ namespace System.Linq.Expressions { - /// - /// Represents creating a new array and possibly initializing the elements of the new array. - /// + /// Represents creating a new array and possibly initializing the elements of the new array. + /// The following table shows the different factory methods that you can use to create a depending on the you require. + /// ||Factory Methods| + /// |----------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------| + /// ||| + /// ||| + /// The following example creates a object that represents creating and initializing a one-dimensional array of strings. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet1"::: + /// The next example creates a object that represents creating a two-dimensional array of strings. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet2"::: [DebuggerTypeProxy(typeof(NewArrayExpressionProxy))] public class NewArrayExpression : Expression { @@ -34,32 +43,26 @@ internal static NewArrayExpression Make(ExpressionType nodeType, Type type, Read } } - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type { get; } - /// - /// Gets the bounds of the array if the value of the property is NewArrayBounds, or the values to initialize the elements of the new array if the value of the property is NewArrayInit. - /// + /// Gets the bounds of the array if the value of the property is , or the values to initialize the elements of the new array if the value of the property is . + /// A of objects which represent either the bounds of the array or the initialization values. public ReadOnlyCollection Expressions { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitNewArray(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public NewArrayExpression Update(IEnumerable expressions) { // Explicit null check here as otherwise wrong parameter name will be used. @@ -105,27 +108,54 @@ internal NewArrayBoundsExpression(Type type, ReadOnlyCollection expr public sealed override ExpressionType NodeType => ExpressionType.NewArrayBounds; } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { #region NewArrayInit - /// - /// Creates a of the specified type from the provided initializers. - /// - /// A Type that represents the element type of the array. - /// The expressions used to create the array elements. - /// A that has the property equal to and the property set to the specified value. + /// Creates a that represents creating a one-dimensional array and initializing it from a list of elements. + /// A that represents the element type of the array. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the property set to the specified value. + /// or is . + /// -or- + /// An element of is . + /// The property of an element of represents a type that is not assignable to the type . + /// The property of each element of must represent a type that is assignable to the type represented by , possibly after it is *quoted*. + /// [!NOTE] + /// > An element will be quoted only if `type` is . Quoting means the element is wrapped in a node. The resulting node is a whose property is the element of `initializers`. + /// ]]> + /// The property of the resulting represents an array type whose rank is 1 and whose element type is . + /// The following example demonstrates how to use the method to create an expression tree that represents creating a one-dimensional string array that is initialized with a list of string expressions. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet1"::: public static NewArrayExpression NewArrayInit(Type type, params Expression[] initializers) { return NewArrayInit(type, (IEnumerable)initializers); } - /// - /// Creates a of the specified type from the provided initializers. - /// - /// A Type that represents the element type of the array. - /// The expressions used to create the array elements. - /// A that has the property equal to and the property set to the specified value. + /// Creates a that represents creating a one-dimensional array and initializing it from a list of elements. + /// A that represents the element type of the array. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the property set to the specified value. + /// or is . + /// -or- + /// An element of is . + /// The property of an element of represents a type that is not assignable to the type that represents. + /// The property of each element of must represent a type that is assignable to the type represented by , possibly after it is *quoted*. + /// [!NOTE] + /// > An element will be quoted only if `type` is . Quoting means the element is wrapped in a node. The resulting node is a whose property is the element of `initializers`. + /// ]]> + /// The property of the resulting represents an array type whose rank is 1 and whose element type is . + /// The following example demonstrates how to use the method to create an expression tree that represents creating a one-dimensional string array that is initialized with a list of string expressions. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet1"::: public static NewArrayExpression NewArrayInit(Type type, IEnumerable initializers) { ContractUtils.RequiresNotNull(type, nameof(type)); @@ -172,27 +202,37 @@ public static NewArrayExpression NewArrayInit(Type type, IEnumerable return NewArrayExpression.Make(ExpressionType.NewArrayInit, type.MakeArrayType(), initializerList); } - #endregion - - #region NewArrayBounds - - /// - /// Creates a that represents creating an array that has a specified rank. - /// - /// A that represents the element type of the array. - /// An array that contains Expression objects to use to populate the collection. - /// A that has the property equal to and the property set to the specified value. + /// Creates a that represents creating an array that has a specified rank. + /// A that represents the element type of the array. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the property set to the specified value. + /// or is . + /// -or- + /// An element of is . + /// The property of an element of does not represent an integral type. + /// The property of the resulting represents an array type whose rank is equal to the length of and whose element type is . + /// The property of each element of must represent an integral type. + /// The following example demonstrates how to use the method to create an expression tree that represents creating a string array that has a rank of 2. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet2"::: public static NewArrayExpression NewArrayBounds(Type type, params Expression[] bounds) { return NewArrayBounds(type, (IEnumerable)bounds); } - /// - /// Creates a that represents creating an array that has a specified rank. - /// - /// A that represents the element type of the array. - /// An that contains objects to use to populate the collection. - /// A that has the property equal to and the property set to the specified value. + /// Creates a that represents creating an array that has a specified rank. + /// A that represents the element type of the array. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the property set to the specified value. + /// or is . + /// -or- + /// An element of is . + /// The property of an element of does not represent an integral type. + /// The property of the resulting represents an array type whose rank is equal to the length of and whose element type is . + /// The property of each element of must represent an integral type. + /// The following example demonstrates how to use the method to create an expression tree that represents creating a string array that has a rank of 2. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet2"::: public static NewArrayExpression NewArrayBounds(Type type, IEnumerable bounds) { ContractUtils.RequiresNotNull(type, nameof(type)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/NewExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/NewExpression.cs index 302d6d06b79653..33fb0a66af8563 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/NewExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/NewExpression.cs @@ -11,9 +11,12 @@ namespace System.Linq.Expressions { - /// - /// Represents a constructor call. - /// + /// Represents a constructor call. + /// Use the factory methods to create a . + /// The value of the property of a object is . + /// The following example creates a that represents the construction of a new instance of a dictionary object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet10"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet10"::: [DebuggerTypeProxy(typeof(NewExpressionProxy))] public class NewExpression : Expression, IArgumentProvider { @@ -26,26 +29,21 @@ internal NewExpression(ConstructorInfo? constructor, IReadOnlyList a Members = members; } - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public override Type Type => Constructor!.DeclaringType!; - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.New; - /// - /// Gets the called constructor. - /// + /// Gets the called constructor. + /// The that represents the called constructor. public ConstructorInfo? Constructor { get; } - /// - /// Gets the arguments to the constructor. - /// + /// Gets the arguments to the constructor. + /// A collection of objects that represent the arguments to the constructor. + /// The property is an empty collection if the constructor takes no arguments. public ReadOnlyCollection Arguments => ExpressionUtils.ReturnReadOnly(ref _arguments); /// @@ -60,26 +58,23 @@ internal NewExpression(ConstructorInfo? constructor, IReadOnlyList a /// public int ArgumentCount => _arguments.Count; - /// - /// Gets the members that can retrieve the values of the fields that were initialized with constructor arguments. - /// + /// Gets the members that can retrieve the values of the fields that were initialized with constructor arguments. + /// A collection of objects that represent the members that can retrieve the values of the fields that were initialized with constructor arguments. + /// The property provides a mapping between the constructor arguments and the type members that correspond to those values. In the case of the construction of an anonymous type, this property maps the constructor arguments to the properties that are exposed by the anonymous type. This mapping information is important because the fields that are initialized by the construction of an anonymous type, or the properties that access those fields, are not discoverable through the or properties of a node. public ReadOnlyCollection? Members { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitNew(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "A NewExpression has already been created. The original creator will get a warning that it is not trim compatible.")] public NewExpression Update(IEnumerable? arguments) @@ -104,35 +99,53 @@ internal NewValueTypeExpression(Type type, ReadOnlyCollection argume public sealed override Type Type { get; } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a new that represents calling the specified constructor that takes no arguments. - /// - /// The to set the property equal to. - /// A that has the property equal to and the property set to the specified value. + /// Creates a that represents calling the specified constructor that takes no arguments. + /// The to set the property equal to. + /// A that has the property equal to and the property set to the specified value. + /// is . + /// The constructor that represents has at least one parameter. + /// The and properties of the resulting are empty collections. The property represents the declaring type of the constructor represented by . public static NewExpression New(ConstructorInfo constructor) { return New(constructor, (IEnumerable?)null); } - /// - /// Creates a new that represents calling the specified constructor that takes no arguments. - /// - /// The to set the property equal to. - /// An array of objects to use to populate the Arguments collection. - /// A that has the property equal to and the and properties set to the specified value. + /// Creates a that represents calling the specified constructor with the specified arguments. + /// The to set the property equal to. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// -or- + /// An element of is . + /// The length of does match the number of parameters for the constructor that represents. + /// -or- + /// The property of an element of is not assignable to the type of the corresponding parameter of the constructor that represents. + /// The parameter must contain the same number of elements as the number of parameters for the constructor represented by . If is , it is considered empty, and the property of the resulting is an empty collection. + /// The property of the resulting represents the declaring type of the constructor represented by . The property is an empty collection. public static NewExpression New(ConstructorInfo constructor, params Expression[]? arguments) { return New(constructor, (IEnumerable?)arguments); } - /// - /// Creates a new that represents calling the specified constructor that takes no arguments. - /// - /// The to set the property equal to. - /// An of objects to use to populate the collection. - /// A that has the property equal to and the and properties set to the specified value. + /// Creates a that represents calling the specified constructor with the specified arguments. + /// The to set the property equal to. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// -or- + /// An element of is . + /// The parameter does not contain the same number of elements as the number of parameters for the constructor that represents. + /// -or- + /// The property of an element of is not assignable to the type of the corresponding parameter of the constructor that represents. + /// The parameter must contain the same number of elements as the number of parameters for the constructor represented by . If is , it is considered empty, and the property of the resulting is an empty collection. + /// The property of the resulting represents the declaring type of the constructor represented by . The property is an empty collection. public static NewExpression New(ConstructorInfo constructor, IEnumerable? arguments) { ContractUtils.RequiresNotNull(constructor, nameof(constructor)); @@ -145,13 +158,26 @@ public static NewExpression New(ConstructorInfo constructor, IEnumerable - /// Creates a new that represents calling the specified constructor with the specified arguments. The members that access the constructor initialized fields are specified. - /// - /// The to set the property equal to. - /// An of objects to use to populate the collection. - /// An of objects to use to populate the collection. - /// A that has the property equal to and the , and properties set to the specified value. + /// Creates a that represents calling the specified constructor with the specified arguments. The members that access the constructor initialized fields are specified. + /// The to set the property equal to. + /// An that contains objects to use to populate the collection. + /// An that contains objects to use to populate the collection. + /// A that has the property equal to and the , and properties set to the specified values. + /// is . + /// -or- + /// An element of is . + /// -or- + /// An element of is . + /// The parameter does not contain the same number of elements as the number of parameters for the constructor that represents. + /// -or- + /// The property of an element of is not assignable to the type of the corresponding parameter of the constructor that represents. + /// -or- + /// The parameter does not have the same number of elements as . + /// -or- + /// An element of has a property that represents a type that is not assignable to the type of the member that is represented by the corresponding element of . + /// The parameter must contain the same number of elements as the number of parameters for the constructor represented by . If is , it is considered empty, and the property of the resulting is an empty collection. + /// If is , the property of the resulting is an empty collection. If is not , it must have the same number of elements as and each element must not be . Each element of must be a , or that represents an instance member on the declaring type of the constructor represented by . If it represents a property, the property must have a `get` accessor. The corresponding element of for each element of must have a property that represents a type that is assignable to the type of the member that the element represents. + /// The property of the resulting represents the declaring type of the constructor that represents. [RequiresUnreferencedCode(PropertyFromAccessorRequiresUnreferencedCode)] public static NewExpression New(ConstructorInfo constructor, IEnumerable? arguments, IEnumerable? members) { @@ -165,24 +191,42 @@ public static NewExpression New(ConstructorInfo constructor, IEnumerable - /// Creates a new that represents calling the specified constructor with the specified arguments. The members that access the constructor initialized fields are specified. - /// - /// The to set the property equal to. - /// An of objects to use to populate the collection. - /// An Array of objects to use to populate the collection. - /// A that has the property equal to and the , and properties set to the specified value. + /// Creates a that represents calling the specified constructor with the specified arguments. The members that access the constructor initialized fields are specified as an array. + /// The to set the property equal to. + /// An that contains objects to use to populate the collection. + /// An array of objects to use to populate the collection. + /// A that has the property equal to and the , and properties set to the specified values. + /// is . + /// -or- + /// An element of is . + /// -or- + /// An element of is . + /// The parameter does not contain the same number of elements as the number of parameters for the constructor that represents. + /// -or- + /// The property of an element of is not assignable to the type of the corresponding parameter of the constructor that represents. + /// -or- + /// The parameter does not have the same number of elements as . + /// -or- + /// An element of has a property that represents a type that is not assignable to the type of the member that is represented by the corresponding element of . + /// The parameter must contain the same number of elements as the number of parameters for the constructor represented by . If is , it is considered empty, and the property of the resulting is an empty collection. + /// If is , the property of the resulting is an empty collection. If is not , it must have the same number of elements as and each element must not be . Each element of must be a , or that represents an instance member on the declaring type of the constructor represented by . If it represents a property, the property must be able to retrieve the value of the associated field. The corresponding element of for each element of must have a property that represents a type that is assignable to the type of the member that the element represents. + /// The property of the resulting represents the declaring type of the constructor that represents. [RequiresUnreferencedCode(PropertyFromAccessorRequiresUnreferencedCode)] public static NewExpression New(ConstructorInfo constructor, IEnumerable? arguments, params MemberInfo[]? members) { return New(constructor, arguments, (IEnumerable?)members); } - /// - /// Creates a that represents calling the parameterless constructor of the specified type. - /// - /// A that has a constructor that takes no arguments. - /// A that has the property equal to and the property set to the that represents the parameterless constructor of the specified type. + /// Creates a that represents calling the parameterless constructor of the specified type. + /// A that has a constructor that takes no arguments. + /// A that has the property equal to and the property set to the that represents the constructor without parameters for the specified type. + /// is . + /// The type that represents does not have a constructor without parameters. + /// The parameter must represent a type that has a constructor without parameters. + /// The and properties of the resulting are empty collections. The property is equal to . + /// The following example demonstrates how to use the method to create a that represents constructing a new instance of a dictionary object by calling the constructor without parameters. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet10"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet10"::: public static NewExpression New( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type) { diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ParameterExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ParameterExpression.cs index 3e3a192d5254e0..e4bec36bdcb70f 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ParameterExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ParameterExpression.cs @@ -6,9 +6,12 @@ namespace System.Linq.Expressions { - /// - /// Represents a named parameter expression. - /// + /// Represents a named parameter expression. + /// Use the factory method to create a . + /// The value of the property of a object is . + /// The following example demonstrates how to create a object that prints the value of a object by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet49"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet49"::: [DebuggerTypeProxy(typeof(ParameterExpressionProxy))] public class ParameterExpression : Expression { @@ -68,33 +71,28 @@ internal static ParameterExpression Make(Type type, string? name, bool isByRef) return new TypedParameterExpression(type, name); } - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public override Type Type => typeof(object); - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.Parameter; - /// - /// The Name of the parameter or variable. - /// + /// Gets the name of the parameter or variable. + /// A that contains the name of the parameter. public string? Name { get; } - /// - /// Indicates that this is to be treated as a ByRef parameter. - /// + /// Indicates that this ParameterExpression is to be treated as a parameter. + /// if this ParameterExpression is a parameter; otherwise, . public bool IsByRef => GetIsByRef(); internal virtual bool GetIsByRef() => false; - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. For example, calls the . + /// The visitor to visit this node with. + /// The result of visiting this node. + /// This default implementation for nodes calls . Override this method to call into a more specific method on a derived visitor class of the class. However, it should still support unknown visitors by calling . protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitParameter(this); @@ -145,34 +143,38 @@ internal PrimitiveParameterExpression(string? name) public sealed override Type Type => typeof(T); } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a node that can be used to identify a parameter or a variable in an expression tree. - /// + /// Creates a node that can be used to identify a parameter or a variable in an expression tree. /// The type of the parameter or variable. - /// A node with the specified name and type. + /// A node with the specified name and type. + /// + /// The following example demonstrates how to create a object that prints the value of a object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet49"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet49"::: public static ParameterExpression Parameter(Type type) { return Parameter(type, name: null); } - /// - /// Creates a node that can be used to identify a parameter or a variable in an expression tree. - /// + /// Creates a node that can be used to identify a parameter or a variable in an expression tree. /// The type of the parameter or variable. - /// A node with the specified name and type. + /// A node with the specified name and type public static ParameterExpression Variable(Type type) { return Variable(type, name: null); } - /// - /// Creates a node that can be used to identify a parameter or a variable in an expression tree. - /// + /// Creates a node that can be used to identify a parameter or a variable in an expression tree. /// The type of the parameter or variable. - /// The name of the parameter or variable, used for debugging or pretty printing purpose only. - /// A node with the specified name and type. + /// The name of the parameter or variable, used for debugging or printing purpose only. + /// A that has the property equal to and the and properties set to the specified values. + /// is . public static ParameterExpression Parameter(Type type, string? name) { Validate(type, allowByRef: true); @@ -185,12 +187,10 @@ public static ParameterExpression Parameter(Type type, string? name) return ParameterExpression.Make(type, name, byref); } - /// - /// Creates a node that can be used to identify a parameter or a variable in an expression tree. - /// + /// Creates a node that can be used to identify a parameter or a variable in an expression tree. /// The type of the parameter or variable. - /// The name of the parameter or variable, used for debugging or pretty printing purpose only. - /// A node with the specified name and type. + /// The name of the parameter or variable. This name is used for debugging or printing purpose only. + /// A node with the specified name and type. public static ParameterExpression Variable(Type type, string? name) { Validate(type, allowByRef: false); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/RuntimeVariablesExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/RuntimeVariablesExpression.cs index a80fa88d8308ab..cc33a72efdde40 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/RuntimeVariablesExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/RuntimeVariablesExpression.cs @@ -9,11 +9,8 @@ namespace System.Linq.Expressions { - /// - /// An expression that provides runtime read/write access to variables. - /// Needed to implement "eval" in some dynamic languages. - /// Evaluates to an instance of when executed. - /// + /// An expression that provides runtime read/write permission for variables. + /// This type is necessary for implementing "eval" in dynamic languages. It evaluates to an instance of at run time. [DebuggerTypeProxy(typeof(RuntimeVariablesExpressionProxy))] public sealed class RuntimeVariablesExpression : Expression { @@ -22,39 +19,29 @@ internal RuntimeVariablesExpression(ReadOnlyCollection vari Variables = variables; } - /// - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type => typeof(IRuntimeVariables); - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this Expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType => ExpressionType.RuntimeVariables; - /// - /// The variables or parameters to which to provide runtime access. - /// + /// The variables or parameters to which to provide runtime access. + /// The read-only collection containing parameters that will be provided the runtime access. public ReadOnlyCollection Variables { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitRuntimeVariables(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public RuntimeVariablesExpression Update(IEnumerable variables) { if (variables != null) @@ -69,23 +56,24 @@ public RuntimeVariablesExpression Update(IEnumerable variab } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates an instance of . - /// - /// An array of objects to use to populate the collection. - /// An instance of that has the property equal to and the property set to the specified value. + /// Creates an instance of . + /// An array of objects to use to populate the collection. + /// An instance of that has the property equal to and the property set to the specified value. public static RuntimeVariablesExpression RuntimeVariables(params ParameterExpression[] variables) { return RuntimeVariables((IEnumerable)variables); } - /// - /// Creates an instance of . - /// - /// A collection of objects to use to populate the collection. - /// An instance of that has the property equal to and the property set to the specified value. + /// Creates an instance of . + /// A collection of objects to use to populate the collection. + /// An instance of that has the property equal to and the property set to the specified value. public static RuntimeVariablesExpression RuntimeVariables(IEnumerable variables) { ContractUtils.RequiresNotNull(variables, nameof(variables)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SwitchCase.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SwitchCase.cs index 3871b4de1bcc6c..5e3d78d1846ac8 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SwitchCase.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SwitchCase.cs @@ -8,9 +8,11 @@ namespace System.Linq.Expressions { - /// - /// Represents one case of a . - /// + /// Represents one case of a . + /// + /// The following example demonstrates how to create an expression that represents a switch statement without a default case by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet34"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet34"::: [DebuggerTypeProxy(typeof(Expression.SwitchCaseProxy))] public sealed class SwitchCase { @@ -20,33 +22,25 @@ internal SwitchCase(Expression body, ReadOnlyCollection testValues) TestValues = testValues; } - /// - /// Gets the values of this case. This case is selected for execution when the matches any of these values. - /// + /// Gets the values of this case. This case is selected for execution when the matches any of these values. + /// The read-only collection of the values for this case block. public ReadOnlyCollection TestValues { get; } - /// - /// Gets the body of this case. - /// + /// Gets the body of this case. + /// The object that represents the body of the case block. public Expression Body { get; } - /// - /// Returns a that represents the current . - /// - /// A that represents the current . + /// Returns a that represents the current . + /// A that represents the current . public override string ToString() { return ExpressionStringBuilder.SwitchCaseToString(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public SwitchCase Update(IEnumerable testValues, Expression body) { if (body == Body & testValues != null) @@ -61,25 +55,31 @@ public SwitchCase Update(IEnumerable testValues, Expression body) } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a for use in a . - /// + /// Creates a for use in a . /// The body of the case. /// The test values of the case. - /// The created . + /// The created . public static SwitchCase SwitchCase(Expression body, params Expression[] testValues) { return SwitchCase(body, (IEnumerable)testValues); } - /// - /// Creates a for use in a . - /// + /// Creates a object to be used in a object. /// The body of the case. /// The test values of the case. - /// The created . + /// The created . + /// All objects in a object must have the same type, unless the has the type `void`. + /// Each object has an implicit `break` statement, which means that there is no implicit fall through from one case label to another. + /// The following example demonstrates how to create an expression that represents a switch statement that has a default case. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet35"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet35"::: public static SwitchCase SwitchCase(Expression body, IEnumerable testValues) { ExpressionUtils.RequiresCanRead(body, nameof(body)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SwitchExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SwitchExpression.cs index f46c49fb8bf4e6..1e25e1eec1557b 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SwitchExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SwitchExpression.cs @@ -9,9 +9,11 @@ namespace System.Linq.Expressions { - /// - /// Represents a control expression that handles multiple selections by passing control to a . - /// + /// Represents a control expression that handles multiple selections by passing control to . + /// + /// The following example demonstrates how to create an expression that represents a switch statement that has a default case by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet35"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet35"::: [DebuggerTypeProxy(typeof(SwitchExpressionProxy))] public sealed class SwitchExpression : Expression { @@ -24,42 +26,33 @@ internal SwitchExpression(Type type, Expression switchValue, Expression? default Cases = cases; } - /// - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type { get; } - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this Expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType => ExpressionType.Switch; - /// - /// Gets the test for the switch. - /// + /// Gets the test for the switch. + /// The object representing the test for the switch. public Expression SwitchValue { get; } - /// - /// Gets the collection of objects for the switch. - /// + /// Gets the collection of objects for the switch. + /// The collection of objects. public ReadOnlyCollection Cases { get; } - /// - /// Gets the test for the switch. - /// + /// Gets the test for the switch. + /// The object representing the test for the switch. public Expression? DefaultBody { get; } - /// - /// Gets the equality comparison method, if any. - /// + /// Gets the equality comparison method, if any. + /// The object representing the equality comparison method. public MethodInfo? Comparison { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitSwitch(this); @@ -78,15 +71,11 @@ internal bool IsLifted } } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public SwitchExpression Update(Expression switchValue, IEnumerable? cases, Expression? defaultBody) { if (switchValue == SwitchValue && defaultBody == DefaultBody && cases != null) @@ -100,80 +89,85 @@ public SwitchExpression Update(Expression switchValue, IEnumerable? } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a . - /// + /// Creates a that represents a statement without a default case. /// The value to be tested against each case. - /// The valid cases for this switch. - /// The created . + /// The set of cases for this switch expression. + /// The created . + /// All objects in a object must have the same type, unless the has the type `void`. + /// Each object has an implicit `break` statement, which means that there is no implicit fall through from one case label to another. + /// If does not match any of the cases, no exception is thrown. + /// The following example demonstrates how to create an expression that represents a switch statement without a default case. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet34"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet34"::: public static SwitchExpression Switch(Expression switchValue, params SwitchCase[]? cases) { return Switch(switchValue, null, null, (IEnumerable?)cases); } - /// - /// Creates a . - /// + /// Creates a that represents a statement that has a default case. /// The value to be tested against each case. - /// The result of the switch if no cases are matched. - /// The valid cases for this switch. - /// The created . + /// The result of the switch if does not match any of the cases. + /// The set of cases for this switch expression. + /// The created . + /// All objects in a object must have the same type, unless the has the type `void`. + /// Each object has an implicit `break` statement, which means that there is no implicit fall through from one case label to another. + /// If does not match any of the cases, the default case represented by is run. + /// The following example demonstrates how to create an expression that represents a switch statement that has a default case. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet35"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet35"::: public static SwitchExpression Switch(Expression switchValue, Expression? defaultBody, params SwitchCase[]? cases) { return Switch(switchValue, defaultBody, null, (IEnumerable?)cases); } - /// - /// Creates a . - /// + /// Creates a that represents a statement that has a default case. /// The value to be tested against each case. - /// The result of the switch if no cases are matched. + /// The result of the switch if does not match any of the cases. /// The equality comparison method to use. - /// The valid cases for this switch. - /// The created . + /// The set of cases for this switch expression. + /// The created . public static SwitchExpression Switch(Expression switchValue, Expression? defaultBody, MethodInfo? comparison, params SwitchCase[]? cases) { return Switch(switchValue, defaultBody, comparison, (IEnumerable?)cases); } - /// - /// Creates a . - /// + /// Creates a that represents a statement that has a default case. /// The result type of the switch. /// The value to be tested against each case. - /// The result of the switch if no cases are matched. + /// The result of the switch if does not match any of the cases. /// The equality comparison method to use. - /// The valid cases for this switch. - /// The created . + /// The set of cases for this switch expression. + /// The created . public static SwitchExpression Switch(Type? type, Expression switchValue, Expression? defaultBody, MethodInfo? comparison, params SwitchCase[]? cases) { return Switch(type, switchValue, defaultBody, comparison, (IEnumerable?)cases); } - /// - /// Creates a . - /// + /// Creates a that represents a statement that has a default case. /// The value to be tested against each case. - /// The result of the switch if no cases are matched. + /// The result of the switch if does not match any of the cases. /// The equality comparison method to use. - /// The valid cases for this switch. - /// The created . + /// The set of cases for this switch expression. + /// The created . public static SwitchExpression Switch(Expression switchValue, Expression? defaultBody, MethodInfo? comparison, IEnumerable? cases) { return Switch(null, switchValue, defaultBody, comparison, cases); } - /// - /// Creates a . - /// + /// Creates a that represents a statement that has a default case. /// The result type of the switch. /// The value to be tested against each case. - /// The result of the switch if no cases are matched. + /// The result of the switch if does not match any of the cases. /// The equality comparison method to use. - /// The valid cases for this switch. - /// The created . + /// The set of cases for this switch expression. + /// The created . public static SwitchExpression Switch(Type? type, Expression switchValue, Expression? defaultBody, MethodInfo? comparison, IEnumerable? cases) { ExpressionUtils.RequiresCanRead(switchValue, nameof(switchValue)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SymbolDocumentInfo.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SymbolDocumentInfo.cs index 542c3a5ac7070b..606b126343aea9 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SymbolDocumentInfo.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/SymbolDocumentInfo.cs @@ -5,10 +5,7 @@ namespace System.Linq.Expressions { - /// - /// Stores information needed to emit debugging symbol information for a - /// source file, in particular the file name and unique language identifier. - /// + /// Stores information necessary to emit debugging symbol information for a source file, in particular the file name and unique language identifier. public class SymbolDocumentInfo { internal SymbolDocumentInfo(string fileName) @@ -17,27 +14,22 @@ internal SymbolDocumentInfo(string fileName) FileName = fileName; } - /// - /// The source file name. - /// + /// The source file name. + /// The string representing the source file name. public string FileName { get; } - /// - /// Returns the language's unique identifier, if any. - /// + /// Returns the language's unique identifier, if any. + /// The language's unique identifier public virtual Guid Language => Guid.Empty; - /// - /// Returns the language vendor's unique identifier, if any. - /// + /// Returns the language vendor's unique identifier, if any. + /// The language vendor's unique identifier. public virtual Guid LanguageVendor => Guid.Empty; internal static readonly Guid DocumentType_Text = new Guid(0x5a869d0b, 0x6611, 0x11d3, 0xbd, 0x2a, 0, 0, 0xf8, 8, 0x49, 0xbd); - /// - /// Returns the document type's unique identifier, if any. - /// Defaults to the guid for a text file. - /// + /// Returns the document type's unique identifier, if any. Defaults to the GUID for a text file. + /// The document type's unique identifier. public virtual Guid DocumentType => DocumentType_Text; } @@ -73,55 +65,46 @@ internal SymbolDocumentWithGuids(string fileName, ref Guid language, ref Guid ve public override Guid DocumentType { get; } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates an instance of . - /// - /// A to set the equal to. - /// A that has the property set to the specified value. + /// Creates an instance of . + /// A to set the equal to. + /// A that has the property set to the specified value. public static SymbolDocumentInfo SymbolDocument(string fileName) { return new SymbolDocumentInfo(fileName); } - /// - /// Creates an instance of . - /// - /// A to set the equal to. - /// A to set the equal to. - /// A that has the - /// and properties set to the specified value. + /// Creates an instance of . + /// A to set the equal to. + /// A to set the equal to. + /// A that has the and properties set to the specified value. public static SymbolDocumentInfo SymbolDocument(string fileName, Guid language) { return new SymbolDocumentWithGuids(fileName, ref language); } - /// - /// Creates an instance of . - /// - /// A to set the equal to. - /// A to set the equal to. - /// A to set the equal to. - /// A that has the - /// and - /// and properties set to the specified value. + /// Creates an instance of . + /// A to set the equal to. + /// A to set the equal to. + /// A to set the equal to. + /// A that has the and and properties set to the specified value. public static SymbolDocumentInfo SymbolDocument(string fileName, Guid language, Guid languageVendor) { return new SymbolDocumentWithGuids(fileName, ref language, ref languageVendor); } - /// - /// Creates an instance of . - /// - /// A to set the equal to. - /// A to set the equal to. - /// A to set the equal to. - /// A to set the equal to. - /// A that has the - /// and - /// and - /// and properties set to the specified value. + /// Creates an instance of . + /// A to set the equal to. + /// A to set the equal to. + /// A to set the equal to. + /// A to set the equal to. + /// A that has the and and and properties set to the specified value. public static SymbolDocumentInfo SymbolDocument(string fileName, Guid language, Guid languageVendor, Guid documentType) { return new SymbolDocumentWithGuids(fileName, ref language, ref languageVendor, ref documentType); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/TryExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/TryExpression.cs index 6908ff02d1471e..e2281b081311b5 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/TryExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/TryExpression.cs @@ -8,16 +8,16 @@ namespace System.Linq.Expressions { - /// - /// Represents a try/catch/finally/fault block. - /// - /// The body is protected by the try block. - /// The handlers consist of a set of s that can either be catch or filters. - /// The fault runs if an exception is thrown. - /// The finally runs regardless of how control exits the body. - /// Only one of fault or finally can be supplied. - /// The return type of the try block must match the return type of any associated catch statements. - /// + /// Represents a try/catch/finally/fault block. + /// The body block is protected by the try block. + /// The handlers consist of a set of expressions that can be either catch statements or filters. + /// The fault block runs if an exception is thrown. + /// The finally block runs regardless of how control exits the body. + /// Only one of fault or finally blocks can be supplied. + /// The return type of the try block must match the return type of any associated catch statements. + /// The following example demonstrates how to create a object that contains a catch statement by using the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet47"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet47"::: [DebuggerTypeProxy(typeof(TryExpressionProxy))] public sealed class TryExpression : Expression { @@ -30,56 +30,44 @@ internal TryExpression(Type type, Expression body, Expression? @finally, Express Fault = fault; } - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type { get; } - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType => ExpressionType.Try; - /// - /// Gets the representing the body of the try block. - /// + /// Gets the representing the body of the try block. + /// The representing the body of the try block. public Expression Body { get; } - /// - /// Gets the collection of s associated with the try block. - /// + /// Gets the collection of expressions associated with the try block. + /// The collection of expressions associated with the try block. public ReadOnlyCollection Handlers { get; } - /// - /// Gets the representing the finally block. - /// + /// Gets the representing the finally block. + /// The representing the finally block. public Expression? Finally { get; } - /// - /// Gets the representing the fault block. - /// + /// Gets the representing the fault block. + /// The representing the fault block. public Expression? Fault { get; } - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitTry(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// The property of the result. - /// The property of the result. - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// The property of the result. + /// The property of the result. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public TryExpression Update(Expression body, IEnumerable? handlers, Expression? @finally, Expression? fault) { if (body == Body & @finally == Finally & fault == Fault) @@ -94,62 +82,65 @@ public TryExpression Update(Expression body, IEnumerable? handlers, } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a representing a try block with a fault block and no catch statements. - /// + /// Creates a representing a try block with a fault block and no catch statements. /// The body of the try block. /// The body of the fault block. - /// The created . + /// The created . public static TryExpression TryFault(Expression body, Expression? fault) { return MakeTry(null, body, null, fault, handlers: null); } - /// - /// Creates a representing a try block with a finally block and no catch statements. - /// + /// Creates a representing a try block with a finally block and no catch statements. /// The body of the try block. /// The body of the finally block. - /// The created . + /// The created . public static TryExpression TryFinally(Expression body, Expression? @finally) { return MakeTry(null, body, @finally, fault: null, handlers: null); } - /// - /// Creates a representing a try block with any number of catch statements and neither a fault nor finally block. - /// + /// Creates a representing a try block with any number of catch statements and neither a fault nor finally block. /// The body of the try block. - /// The array of zero or more s representing the catch statements to be associated with the try block. - /// The created . + /// The array of zero or more expressions representing the catch statements to be associated with the try block. + /// The created . + /// + /// The following example demonstrates how to create a object that contains a catch statement. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet47"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet47"::: public static TryExpression TryCatch(Expression body, params CatchBlock[]? handlers) { return MakeTry(null, body, null, null, handlers); } - /// - /// Creates a representing a try block with any number of catch statements and a finally block. - /// + /// Creates a representing a try block with any number of catch statements and a finally block. /// The body of the try block. /// The body of the finally block. - /// The array of zero or more s representing the catch statements to be associated with the try block. - /// The created . + /// The array of zero or more expressions representing the catch statements to be associated with the try block. + /// The created . + /// + /// The following example demonstrates how to create a object that contains a catch statement and a finally statement. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet48"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet48"::: public static TryExpression TryCatchFinally(Expression body, Expression? @finally, params CatchBlock[]? handlers) { return MakeTry(null, body, @finally, null, handlers); } - /// - /// Creates a representing a try block with the specified elements. - /// + /// Creates a representing a try block with the specified elements. /// The result type of the try expression. If null, body and all handlers must have identical type. /// The body of the try block. /// The body of the finally block. Pass null if the try block has no finally block associated with it. - /// The body of the t block. Pass null if the try block has no fault block associated with it. - /// A collection of s representing the catch statements to be associated with the try block. - /// The created . + /// The body of the fault block. Pass null if the try block has no fault block associated with it. + /// A collection of s representing the catch statements to be associated with the try block. + /// The created . public static TryExpression MakeTry(Type? type, Expression body, Expression? @finally, Expression? fault, IEnumerable? handlers) { ExpressionUtils.RequiresCanRead(body, nameof(body)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/TypeBinaryExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/TypeBinaryExpression.cs index 2a4ce5e2f763e3..954442e55d1daa 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/TypeBinaryExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/TypeBinaryExpression.cs @@ -8,9 +8,13 @@ namespace System.Linq.Expressions { - /// - /// Represents an operation between an expression and a type. - /// + /// Represents an operation between an expression and a type. + /// A type test is an example of an operation between an expression and a type. + /// Use the factory method to create a . + /// The value of the property of a object is . + /// The following example creates a object that represents a type test of a string value against the type. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet12"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet12"::: [DebuggerTypeProxy(typeof(TypeBinaryExpressionProxy))] public sealed class TypeBinaryExpression : Expression { @@ -21,27 +25,20 @@ internal TypeBinaryExpression(Expression expression, Type typeOperand, Expressio NodeType = nodeType; } - /// - /// Gets the static type of the expression that this represents. - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type => typeof(bool); - /// - /// Returns the node type of this Expression. Extension nodes should return - /// ExpressionType.Extension when overriding this method. - /// - /// The of the expression. + /// Returns the node type of this Expression. Extension nodes should return when overriding this method. + /// The of the expression. public sealed override ExpressionType NodeType { get; } - /// - /// Gets the expression operand of a type test operation. - /// + /// Gets the expression operand of a type test operation. + /// An that represents the expression operand of a type test operation. public Expression Expression { get; } - /// - /// Gets the type operand of a type test operation. - /// + /// Gets the type operand of a type test operation. + /// A that represents the type operand of a type test operation. public Type TypeOperand { get; } #region Reduce TypeEqual @@ -150,22 +147,17 @@ private Expression ReduceConstantTypeEqual() } #endregion - - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitTypeBinary(this); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. public TypeBinaryExpression Update(Expression expression) { if (expression == Expression) @@ -180,14 +172,22 @@ public TypeBinaryExpression Update(Expression expression) } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a . - /// - /// An to set the property equal to. - /// A to set the property equal to. - /// A for which the property is equal to and for which the and properties are set to the specified values. + /// Creates a . + /// An to set the property equal to. + /// A to set the property equal to. + /// A for which the property is equal to and for which the and properties are set to the specified values. + /// or is . + /// The property of the resulting represents . + /// The following example demonstrates how to use the method to create a that represents a type test of a string value against the type. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet12"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet12"::: public static TypeBinaryExpression TypeIs(Expression expression, Type type) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -197,12 +197,10 @@ public static TypeBinaryExpression TypeIs(Expression expression, Type type) return new TypeBinaryExpression(expression, type, ExpressionType.TypeIs); } - /// - /// Creates a that compares run-time type identity. - /// - /// An to set the property equal to. - /// A to set the property equal to. - /// A for which the property is equal to and for which the and properties are set to the specified values. + /// Creates a that compares run-time type identity. + /// An to set the property equal to. + /// A to set the property equal to. + /// A for which the property is equal to and for which the and properties are set to the specified values. public static TypeBinaryExpression TypeEqual(Expression expression, Type type) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/UnaryExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/UnaryExpression.cs index 99fb5c4ba2691d..a3a60c138b2825 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/UnaryExpression.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/UnaryExpression.cs @@ -9,9 +9,23 @@ namespace System.Linq.Expressions { - /// - /// Represents an expression that has a unary operator. - /// + /// Represents an expression that has a unary operator. + /// The following table summarizes the factory methods that can be used to create a that has a specific node type. + /// ||Factory Method| + /// |----------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// ||| + /// In addition, the methods can also be used to create a . These factory methods can be used to create a of any node type that represents a unary operation. The parameter of these methods that is of type specifies the desired node type. + /// The following example creates a object that represents the reference conversion of a non-nullable integer expression to the nullable integer type. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet11"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet11"::: [DebuggerTypeProxy(typeof(UnaryExpressionProxy))] public sealed class UnaryExpression : Expression { @@ -23,34 +37,25 @@ internal UnaryExpression(ExpressionType nodeType, Expression expression, Type ty Type = type; } - /// - /// Gets the static type of the expression that this represents. (Inherited from .) - /// - /// The that represents the static type of the expression. + /// Gets the static type of the expression that this represents. + /// The that represents the static type of the expression. public sealed override Type Type { get; } - /// - /// Returns the node type of this . (Inherited from .) - /// - /// The that represents this expression. + /// Returns the node type of this . + /// The that represents this expression. public sealed override ExpressionType NodeType { get; } - /// - /// Gets the operand of the unary operation. - /// - /// An that represents the operand of the unary operation. Returns null if node type is with no operand. + /// Gets the operand of the unary operation. + /// An that represents the operand of the unary operation. public Expression Operand { get; } - /// - /// Gets the implementing method for the unary operation. - /// - /// The that represents the implementing method. + /// Gets the implementing method for the unary operation. + /// The that represents the implementing method. public MethodInfo? Method { get; } - /// - /// Gets a value that indicates whether the expression tree node represents a lifted call to an operator. - /// - /// true if the node represents a lifted call; otherwise, false. + /// Gets a value that indicates whether the expression tree node represents a lifted call to an operator. + /// if the node represents a lifted call; otherwise, . + /// An operator call is *lifted* if the operator expects a non-nullable operand but a nullable operand is passed to it. public bool IsLifted { get @@ -70,23 +75,21 @@ public bool IsLifted } } - /// - /// Gets a value that indicates whether the expression tree node represents a lifted call to an operator whose return type is lifted to a nullable type. - /// - /// true if the operator's return type is lifted to a nullable type; otherwise, false. + /// Gets a value that indicates whether the expression tree node represents a lifted call to an operator whose return type is lifted to a nullable type. + /// if the operator's return type is lifted to a nullable type; otherwise, . + /// An operator call is *lifted* if the operator expects a non-nullable operand but a nullable operand is passed to it. If the value of is , the operator returns a nullable type and if the nullable operand evaluates to , the operator returns . public bool IsLiftedToNull => IsLifted && this.Type.IsNullableType(); - /// - /// Dispatches to the specific visit method for this node type. - /// + /// Dispatches to the specific visit method for this node type. + /// The visitor to visit this node with. + /// The result of visiting this node. protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitUnary(this); } - /// - /// Gets a value that indicates whether the expression tree node can be reduced. - /// + /// Gets a value that indicates whether the expression tree node can be reduced. + /// if a node can be reduced; otherwise, . public override bool CanReduce { get @@ -103,13 +106,10 @@ public override bool CanReduce } } - /// - /// Reduces the expression node to a simpler expression. - /// If CanReduce returns true, this should return a valid expression. - /// This method is allowed to return another node which itself - /// must be reduced. - /// + /// Reduces the expression node to a simpler expression. /// The reduced expression. + /// If the `CanReduce` method returns true, this should return a valid expression. + /// This method can return another node which itself must be reduced. public override Expression Reduce() { if (CanReduce) @@ -272,13 +272,9 @@ private Expression ReduceIndex() return Block(new TrueReadOnlyCollection(temps), new TrueReadOnlyCollection(block)); } - /// - /// Creates a new expression that is like this one, but using the - /// supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. + /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. + /// The property of the result. + /// This expression if no children are changed or an expression with the updated children. [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "A UnaryExpression has already been created. The original creator will get a warning that it is not trim compatible.")] public UnaryExpression Update(Expression operand) @@ -291,33 +287,36 @@ public UnaryExpression Update(Expression operand) } } + /// Provides the base class from which the classes that represent expression tree nodes are derived. It also contains ( in Visual Basic) factory methods to create the various node types. This is an class. + /// + /// The following code example shows how to create a block expression. The block expression consists of two objects and one object. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet13"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet13"::: public partial class Expression { - /// - /// Creates a , given an operand, by calling the appropriate factory method. - /// - /// The that specifies the type of unary operation. - /// An that represents the operand. - /// The that specifies the type to be converted to (pass null if not applicable). - /// The that results from calling the appropriate factory method. - /// Thrown when does not correspond to a unary expression. - /// Thrown when is null. + /// Creates a , given an operand, by calling the appropriate factory method. + /// The that specifies the type of unary operation. + /// An that represents the operand. + /// The that specifies the type to be converted to (pass if not applicable). + /// The that results from calling the appropriate factory method. + /// is . + /// does not correspond to a unary expression node. + /// The parameter determines which factory method this method calls. For example, if is equal to , this method invokes . The parameter is ignored if it does not apply to the factory method that is called. [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static UnaryExpression MakeUnary(ExpressionType unaryType, Expression operand, Type type) { return MakeUnary(unaryType, operand, type, method: null); } - /// - /// Creates a , given an operand and implementing method, by calling the appropriate factory method. - /// - /// The that specifies the type of unary operation. - /// An that represents the operand. - /// The that specifies the type to be converted to (pass null if not applicable). - /// The that represents the implementing method. - /// The that results from calling the appropriate factory method. - /// Thrown when does not correspond to a unary expression. - /// Thrown when is null. + /// Creates a , given an operand and implementing method, by calling the appropriate factory method. + /// The that specifies the type of unary operation. + /// An that represents the operand. + /// The that specifies the type to be converted to (pass if not applicable). + /// The that represents the implementing method. + /// The that results from calling the appropriate factory method. + /// is . + /// does not correspond to a unary expression node. + /// The parameter determines which factory method this method calls. For example, if is equal to , this method invokes . The and parameters are ignored if they do not apply to the factory method that is called. [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static UnaryExpression MakeUnary(ExpressionType unaryType, Expression operand, Type type, MethodInfo? method) => unaryType switch @@ -451,27 +450,53 @@ private static UnaryExpression GetMethodBasedCoercionOperator(ExpressionType una throw Error.OperandTypesDoNotMatchParameters(unaryType, method.Name); } - /// - /// Creates a that represents an arithmetic negation operation. - /// - /// An to set the property equal to. - /// A that has the property equal to and the properties set to the specified value. - /// Thrown when is null. - /// Thrown when the unary minus operator is not defined for .Type. + /// Creates a that represents an arithmetic negation operation. + /// An to set the property equal to. + /// A that has the property equal to and the property set to the specified value. + /// is . + /// The unary minus operator is not defined for .Type. + /// The property of the resulting is set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are false. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If .Type is a user-defined type that defines the unary minus operator, the that represents that operator is the implementing method. + /// - Otherwise, if .Type is a numeric type, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type is a nullable value type and the corresponding non-nullable value type is equal to the argument type of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is , the type of the node is .Type. If .Type is non-nullable, the node is not lifted. Otherwise, the node is lifted. + /// The following example demonstrates how to create an expression that represents an arithmetic negation operation. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet50"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet50"::: public static UnaryExpression Negate(Expression expression) { return Negate(expression, method: null); } - /// - /// Creates a that represents an arithmetic negation operation. - /// - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to and the and properties set to the specified value. - /// Thrown when is null. - /// Thrown when is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. - /// Thrown when is null and the unary minus operator is not defined for .Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by method. + /// Creates a that represents an arithmetic negation operation. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly one argument. + /// is and the unary minus operator is not defined for .Type. + /// -or- + /// .Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by . + /// The property of the resulting is set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are false. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes one argument, it is the implementing method for the node. + /// - If .Type is a user-defined type that defines the unary minus operator, the that represents that operator is the implementing method. + /// - Otherwise, if .Type is a numeric type, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type is a nullable value type and the corresponding non-nullable value type is equal to the argument type of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is , the type of the node is .Type. If .Type is non-nullable, the node is not lifted. Otherwise, the node is lifted. public static UnaryExpression Negate(Expression expression, MethodInfo? method) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -486,27 +511,50 @@ public static UnaryExpression Negate(Expression expression, MethodInfo? method) return GetMethodBasedUnaryOperator(ExpressionType.Negate, expression, method); } - /// - /// Creates a that represents a unary plus operation. - /// - /// An to set the property equal to. - /// A that has the property equal to and the property set to the specified value. - /// Thrown when is null. - /// Thrown when the unary minus operator is not defined for .Type. + /// Creates a that represents a unary plus operation. + /// An to set the property equal to. + /// A that has the property equal to and the property set to the specified value. + /// is . + /// The unary plus operator is not defined for .Type. + /// The property of the resulting is set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are false. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If .Type is a user-defined type that defines the unary plus operator, the that represents that operator is the implementing method. + /// - Otherwise, if .Type is a numeric type, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type is a nullable value type and the corresponding non-nullable value type is equal to the argument type of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is , the type of the node is .Type. If .Type is non-nullable, the node is not lifted. Otherwise, the node is lifted. public static UnaryExpression UnaryPlus(Expression expression) { return UnaryPlus(expression, method: null); } - /// - /// Creates a that represents a unary plus operation. - /// - /// An to set the property equal to. - /// A to set the property equal to. - /// A that has the property equal to and the and property set to the specified value. - /// Thrown when is null. - /// Thrown when is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. - /// Thrown when is null and the unary minus operator is not defined for .Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by method. + /// Creates a that represents a unary plus operation. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly one argument. + /// is and the unary plus operator is not defined for .Type. + /// -or- + /// .Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by . + /// The property of the resulting is set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are false. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes one argument, it is the implementing method for the node. + /// - If .Type is a user-defined type that defines the unary plus operator, the that represents that operator is the implementing method. + /// - Otherwise, if .Type is a numeric type, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type is a nullable value type and the corresponding non-nullable value type is equal to the argument type of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is , the type of the node is .Type. If .Type is non-nullable, the node is not lifted. Otherwise, the node is lifted. public static UnaryExpression UnaryPlus(Expression expression, MethodInfo? method) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -521,26 +569,50 @@ public static UnaryExpression UnaryPlus(Expression expression, MethodInfo? metho return GetMethodBasedUnaryOperator(ExpressionType.UnaryPlus, expression, method); } - /// Creates a that represents an arithmetic negation operation that has overflow checking. - /// A that has the property equal to and the property set to the specified value. - /// An to set the property equal to. - /// Thrown when is null. - /// Thrown when the unary minus operator is not defined for .Type. + /// Creates a that represents an arithmetic negation operation that has overflow checking. + /// An to set the property equal to. + /// A that has the property equal to and the property set to the specified value. + /// is . + /// The unary minus operator is not defined for .Type. + /// The property of the resulting is set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are false. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If .Type is a user-defined type that defines the unary minus operator, the that represents that operator is the implementing method. + /// - Otherwise, if .Type is a numeric type, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type is a nullable value type and the corresponding non-nullable value type is equal to the argument type of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is , the type of the node is .Type. If .Type is non-nullable, the node is not lifted. Otherwise, the node is lifted. public static UnaryExpression NegateChecked(Expression expression) { return NegateChecked(expression, method: null); } - /// Creates a that represents an arithmetic negation operation that has overflow checking. The implementing method can be specified. - /// A that has the property equal to and the and properties set to the specified values. - /// An to set the property equal to. - /// A to set the property equal to. - /// - /// is null. - /// - /// is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. - /// - /// is null and the unary minus operator is not defined for .Type.-or-.Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by . + /// Creates a that represents an arithmetic negation operation that has overflow checking. The implementing method can be specified. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly one argument. + /// is and the unary minus operator is not defined for .Type. + /// -or- + /// .Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by . + /// The property of the resulting is set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are false. + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes one argument, it is the implementing method for the node. + /// - If .Type is a user-defined type that defines the unary minus operator, the that represents that operator is the implementing method. + /// - Otherwise, if .Type is a numeric type, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type is a nullable value type and the corresponding non-nullable value type is equal to the argument type of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is , the type of the node is .Type. If .Type is non-nullable, the node is not lifted. Otherwise, the node is lifted. public static UnaryExpression NegateChecked(Expression expression, MethodInfo? method) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -555,27 +627,53 @@ public static UnaryExpression NegateChecked(Expression expression, MethodInfo? m return GetMethodBasedUnaryOperator(ExpressionType.NegateChecked, expression, method); } - /// Creates a that represents a bitwise complement operation. - /// A that has the property equal to and the property set to the specified value. - /// An to set the property equal to. - /// - /// is null. - /// The unary not operator is not defined for .Type. + /// Creates a that represents a bitwise complement operation. + /// An to set the property equal to. + /// A that has the property equal to and the property set to the specified value. + /// is . + /// The unary not operator is not defined for .Type. + /// The property of the resulting is set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If .Type is a user-defined type that defines the unary not operator, the that represents that operator is the implementing method. + /// - Otherwise, if .Type is a numeric or Boolean type, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type is a nullable value type and the corresponding non-nullable type is equal to the argument type of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is , the type of the node is .Type. If .Type is non-nullable, the node is not lifted. Otherwise, the node is lifted. + /// The following example demonstrates how to create an expression that represents a logical NOT operation. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet51"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet51"::: public static UnaryExpression Not(Expression expression) { return Not(expression, method: null); } - /// Creates a that represents a bitwise complement operation. The implementing method can be specified. - /// A that has the property equal to and the and properties set to the specified values. - /// An to set the property equal to. - /// A to set the property equal to. - /// - /// is null. - /// - /// is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. - /// - /// is null and the unary not operator is not defined for .Type.-or-.Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by . + /// Creates a that represents a bitwise complement operation. The implementing method can be specified. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly one argument. + /// is and the unary not operator is not defined for .Type. + /// -or- + /// .Type (or its corresponding non-nullable type if it is a nullable value type) is not assignable to the argument type of the method represented by . + /// The property of the resulting is set to the implementing method. The property is set to the type of the node. If the node is lifted, the and properties are both . Otherwise, they are . + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If is not and it represents a non-void, (`Shared` in Visual Basic) method that takes one argument, it is the implementing method for the node. + /// - If .Type is a user-defined type that defines the unary not operator, the that represents that operator is the implementing method. + /// - Otherwise, if .Type is a numeric type, the implementing method is . + /// #### Node Type and Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method, the node is not lifted. The type of the node is the return type of the implementing method. + /// - If the following two conditions are satisfied, the node is lifted and the type of the node is the nullable type that corresponds to the return type of the implementing method: + /// - .Type is a nullable value type and the corresponding non-nullable value type is equal to the argument type of the implementing method. + /// - The return type of the implementing method is a non-nullable value type. + /// If the implementing method is , the type of the node is .Type. If .Type is non-nullable, the node is not lifted. Otherwise, the node is lifted. public static UnaryExpression Not(Expression expression, MethodInfo? method) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -595,22 +693,18 @@ public static UnaryExpression Not(Expression expression, MethodInfo? method) return GetMethodBasedUnaryOperator(ExpressionType.Not, expression, method); } - /// - /// Returns whether the expression evaluates to false. - /// - /// An to evaluate. - /// An instance of . + /// Returns whether the expression evaluates to false. + /// An to evaluate. + /// An instance of . public static UnaryExpression IsFalse(Expression expression) { return IsFalse(expression, method: null); } - /// - /// Returns whether the expression evaluates to false. - /// - /// An to evaluate. - /// A that represents the implementing method. - /// An instance of . + /// Returns whether the expression evaluates to false. + /// An to evaluate. + /// A that represents the implementing method. + /// An instance of . public static UnaryExpression IsFalse(Expression expression, MethodInfo? method) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -625,22 +719,18 @@ public static UnaryExpression IsFalse(Expression expression, MethodInfo? method) return GetMethodBasedUnaryOperator(ExpressionType.IsFalse, expression, method); } - /// - /// Returns whether the expression evaluates to true. - /// - /// An to evaluate. - /// An instance of . + /// Returns whether the expression evaluates to true. + /// An to evaluate. + /// An instance of . public static UnaryExpression IsTrue(Expression expression) { return IsTrue(expression, method: null); } - /// - /// Returns whether the expression evaluates to true. - /// - /// An to evaluate. - /// A that represents the implementing method. - /// An instance of . + /// Returns whether the expression evaluates to true. + /// An to evaluate. + /// A that represents the implementing method. + /// An instance of . public static UnaryExpression IsTrue(Expression expression, MethodInfo? method) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -655,22 +745,18 @@ public static UnaryExpression IsTrue(Expression expression, MethodInfo? method) return GetMethodBasedUnaryOperator(ExpressionType.IsTrue, expression, method); } - /// - /// Returns the expression representing the ones complement. - /// - /// An . - /// An instance of . + /// Returns the expression representing the ones complement. + /// An . + /// An instance of . public static UnaryExpression OnesComplement(Expression expression) { return OnesComplement(expression, method: null); } - /// - /// Returns the expression representing the ones complement. - /// - /// An . - /// A that represents the implementing method. - /// An instance of . + /// Returns the expression representing the ones complement. + /// An . + /// A that represents the implementing method. + /// An instance of . public static UnaryExpression OnesComplement(Expression expression, MethodInfo? method) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -685,12 +771,15 @@ public static UnaryExpression OnesComplement(Expression expression, MethodInfo? return GetMethodBasedUnaryOperator(ExpressionType.OnesComplement, expression, method); } - /// Creates a that represents an explicit reference or boxing conversion where null is supplied if the conversion fails. - /// A that has the property equal to and the and properties set to the specified values. - /// An to set the property equal to. - /// A to set the property equal to. - /// - /// or is null. + /// Creates a that represents an explicit reference or boxing conversion where is supplied if the conversion fails. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// The property of the resulting is . The and properties are both . + /// The following example demonstrates how to use the method to create a that represents the reference conversion of a non-nullable integer expression to the nullable integer type. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/CS/Expression.cs" id="Snippet11"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Expressions.Expression/VB/Expression.vb" id="Snippet11"::: public static UnaryExpression TypeAs(Expression expression, Type type) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -704,12 +793,10 @@ public static UnaryExpression TypeAs(Expression expression, Type type) return new UnaryExpression(ExpressionType.TypeAs, expression, type, null); } - /// - /// Creates a that represents an explicit unboxing. - /// - /// An to unbox. - /// The new of the expression. - /// An instance of . + /// Creates a that represents an explicit unboxing. + /// An to unbox. + /// The new of the expression. + /// An instance of . public static UnaryExpression Unbox(Expression expression, Type type) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -723,29 +810,64 @@ public static UnaryExpression Unbox(Expression expression, Type type) return new UnaryExpression(ExpressionType.Unbox, expression, type, null); } - /// Creates a that represents a conversion operation. - /// A that has the property equal to and the and properties set to the specified values. - /// An to set the property equal to. - /// A to set the property equal to. - /// - /// or is null. - /// No conversion operator is defined between .Type and . + /// Creates a that represents a type conversion operation. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// No conversion operator is defined between .Type and . + /// The property of the resulting is set to the implementing method. The property is . If the node is lifted, is . Otherwise, it is . + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If either .Type or is a user-defined type that defines an implicit or explicit conversion operator, the that represents that operator is the implementing method. + /// - Otherwise: + /// - If both .Type and represent numeric or Boolean types, or nullable or non-nullable enumeration types, the implementing method is . + /// - If either .Type or is a reference type and an explicit boxing, unboxing, or reference conversion exists from .Type to , the implementing method is . + /// #### Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method and the return type of the implementing method is assignable to , the node is not lifted. + /// - If one or both of .Type or is a nullable value type and the corresponding non-nullable value types are equal to the argument type and the return type of the implementing method respectively, the node is lifted. + /// If the implementing method is : + /// - If both .Type and are non-nullable, the node is not lifted. + /// - Otherwise the node is lifted. + /// The following code example shows how to create an expression that represents a type conversion operation. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet23"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet23"::: public static UnaryExpression Convert(Expression expression, Type type) { return Convert(expression, type, method: null); } - /// Creates a that represents a conversion operation for which the implementing method is specified. - /// A that has the property equal to and the , , and properties set to the specified values. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// - /// or is null. - /// - /// is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. - /// More than one method that matches the description was found. - /// No conversion operator is defined between .Type and .-or-.Type is not assignable to the argument type of the method represented by .-or-The return type of the method represented by is not assignable to .-or-.Type or is a nullable value type and the corresponding non-nullable value type does not equal the argument type or the return type, respectively, of the method represented by . + /// Creates a that represents a conversion operation for which the implementing method is specified. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly one argument. + /// No conversion operator is defined between .Type and . + /// -or- + /// .Type is not assignable to the argument type of the method represented by . + /// -or- + /// The return type of the method represented by is not assignable to . + /// -or- + /// .Type or is a nullable value type and the corresponding non-nullable value type does not equal the argument type or the return type, respectively, of the method represented by . + /// More than one method that matches the description was found. + /// The property of the resulting is set to the implementing method. The property is . If the node is lifted, is . Otherwise, it is . + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If method is not , it is the implementing method. It must represent a non-void, (`Shared` in Visual Basic) method that takes one argument. + /// - Otherwise, if either .Type or is a user-defined type that defines an implicit or explicit conversion operator, the that represents that operator is the implementing method. + /// - Otherwise: + /// - If both .Type and represent numeric or Boolean types, or nullable or non-nullable enumeration types, the implementing method is . + /// - If either .Type or is a reference type and an explicit boxing, unboxing, or reference conversion exists from .Type to , the implementing method is . + /// #### Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method and the return type of the implementing method is assignable to , the node is not lifted. + /// - If either or both of .Type or are a nullable value type and the corresponding non-nullable value types are equal to the argument type and the return type of the implementing method respectively, the node is lifted. + /// If the implementing method is : + /// - If both .Type and are non-nullable, the node is not lifted. + /// - Otherwise the node is lifted. [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static UnaryExpression Convert(Expression expression, Type type, MethodInfo? method) { @@ -764,30 +886,62 @@ public static UnaryExpression Convert(Expression expression, Type type, MethodIn return GetMethodBasedCoercionOperator(ExpressionType.Convert, expression, type, method); } - /// Creates a that represents a conversion operation that throws an exception if the target type is overflowed. - /// A that has the property equal to and the and properties set to the specified values. - /// An to set the property equal to. - /// A to set the property equal to. - /// - /// or is null. - /// No conversion operator is defined between .Type and . + /// Creates a that represents a conversion operation that throws an exception if the target type is overflowed. + /// An to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the and properties set to the specified values. + /// or is . + /// No conversion operator is defined between .Type and . + /// The property of the resulting is set to the implementing method. The property is . If the node is lifted, is . Otherwise, it is . + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If either .Type or is a user-defined type that defines an implicit or explicit conversion operator, the that represents that operator is the implementing method. + /// - Otherwise: + /// - If both .Type and represent numeric or Boolean types, or nullable or non-nullable enumeration types, the implementing method is . + /// - If either .Type or is a reference type and an explicit boxing, unboxing, or reference conversion exists from .Type to , the implementing method is . + /// #### Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method and the return type of the implementing method is assignable to , the node is not lifted. + /// - If either or both of .Type or are a nullable value type and the corresponding non-nullable value types are equal to the argument type and the return type of the implementing method respectively, the node is lifted. + /// If the implementing method is : + /// - If both .Type and are non-nullable, the node is not lifted. + /// - Otherwise the node is lifted. [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static UnaryExpression ConvertChecked(Expression expression, Type type) { return ConvertChecked(expression, type, method: null); } - /// Creates a that represents a conversion operation that throws an exception if the target type is overflowed and for which the implementing method is specified. - /// A that has the property equal to and the , , and properties set to the specified values. - /// An to set the property equal to. - /// A to set the property equal to. - /// A to set the property equal to. - /// - /// or is null. - /// - /// is not null and the method it represents returns void, is not static (Shared in Visual Basic), or does not take exactly one argument. - /// More than one method that matches the description was found. - /// No conversion operator is defined between .Type and .-or-.Type is not assignable to the argument type of the method represented by .-or-The return type of the method represented by is not assignable to .-or-.Type or is a nullable value type and the corresponding non-nullable value type does not equal the argument type or the return type, respectively, of the method represented by . + /// Creates a that represents a conversion operation that throws an exception if the target type is overflowed and for which the implementing method is specified. + /// An to set the property equal to. + /// A to set the property equal to. + /// A to set the property equal to. + /// A that has the property equal to and the , , and properties set to the specified values. + /// or is . + /// is not and the method it represents returns , is not ( in Visual Basic), or does not take exactly one argument. + /// No conversion operator is defined between .Type and . + /// -or- + /// .Type is not assignable to the argument type of the method represented by . + /// -or- + /// The return type of the method represented by is not assignable to . + /// -or- + /// .Type or is a nullable value type and the corresponding non-nullable value type does not equal the argument type or the return type, respectively, of the method represented by . + /// More than one method that matches the description was found. + /// The property of the resulting is set to the implementing method. The property is . If the node is lifted, is . Otherwise, it is . + /// #### Implementing Method + /// The following rules determine the implementing method for the operation: + /// - If method is not , it is the implementing method. It must represent a non-void, (`Shared` in Visual Basic) method that takes one argument. + /// - Otherwise, if either .Type or is a user-defined type that defines an implicit or explicit conversion operator, the that represents that operator is the implementing method. + /// - Otherwise: + /// - If both .Type and represent numeric or Boolean types, or nullable or non-nullable enumeration types, the implementing method is . + /// - If either .Type or is a reference type and an explicit boxing, unboxing, or reference conversion exists from .Type to , the implementing method is . + /// #### Lifted versus Non-Lifted + /// If the implementing method is not : + /// - If .Type is assignable to the argument type of the implementing method and the return type of the implementing method is assignable to , the node is not lifted. + /// - If either or both of .Type or are a nullable value type and the corresponding non-nullable value types are equal to the argument type and the return type of the implementing method respectively, the node is lifted. + /// If the implementing method is : + /// - If both .Type and are non-nullable, the node is not lifted. + /// - Otherwise the node is lifted. [RequiresUnreferencedCode(ExpressionRequiresUnreferencedCode)] public static UnaryExpression ConvertChecked(Expression expression, Type type, MethodInfo? method) { @@ -809,13 +963,13 @@ public static UnaryExpression ConvertChecked(Expression expression, Type type, M return GetMethodBasedCoercionOperator(ExpressionType.ConvertChecked, expression, type, method); } - /// Creates a that represents getting the length of a one-dimensional, zero-based array. - /// A that has the property equal to and the property equal to . - /// An to set the property equal to. - /// - /// is null. - /// - /// .Type does not represent a single-dimensional, zero-based array type. + /// Creates a that represents an expression for obtaining the length of a one-dimensional array. + /// An to set the property equal to. + /// A that has the property equal to and the property equal to . + /// is . + /// .Type does not represent an array type. + /// The property of must represent an array type. + /// The property of the resulting is equal to . The property is , and both and are set to . public static UnaryExpression ArrayLength(Expression array) { ExpressionUtils.RequiresCanRead(array, nameof(array)); @@ -832,11 +986,11 @@ public static UnaryExpression ArrayLength(Expression array) return new UnaryExpression(ExpressionType.ArrayLength, array, typeof(int), null); } - /// Creates a that represents an expression that has a constant value of type . - /// A that has the property equal to and the property set to the specified value. - /// An to set the property equal to. - /// - /// is null. + /// Creates a that represents an expression that has a constant value of type . + /// An to set the property equal to. + /// A that has the property equal to and the property set to the specified value. + /// is . + /// The property of the resulting represents the constructed type , where the type argument is the type represented by .Type. The property is . Both and are . public static UnaryExpression Quote(Expression expression) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -849,41 +1003,37 @@ public static UnaryExpression Quote(Expression expression) return new UnaryExpression(ExpressionType.Quote, lambda, lambda.PublicType, null); } - /// - /// Creates a that represents a rethrowing of an exception. - /// - /// A that represents a rethrowing of an exception. + /// Creates a that represents a rethrowing of an exception. + /// A that represents a rethrowing of an exception. public static UnaryExpression Rethrow() { return Throw(value: null); } - /// - /// Creates a that represents a rethrowing of an exception with a given type. - /// - /// The new of the expression. - /// A that represents a rethrowing of an exception. + /// Creates a that represents a rethrowing of an exception with a given type. + /// The new of the expression. + /// A that represents a rethrowing of an exception. public static UnaryExpression Rethrow(Type type) { return Throw(null, type); } - /// - /// Creates a that represents a throwing of an exception. - /// - /// An . - /// A that represents the exception. + /// Creates a that represents a throwing of an exception. + /// An . + /// A that represents the exception. + /// + /// The following example demonstrates how to create a object that uses the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet47"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet47"::: public static UnaryExpression Throw(Expression? value) { return Throw(value, typeof(void)); } - /// - /// Creates a that represents a throwing of a value with a given type. - /// - /// An . - /// The new of the expression. - /// A that represents the exception. + /// Creates a that represents a throwing of an exception with a given type. + /// An . + /// The new of the expression. + /// A that represents the exception. public static UnaryExpression Throw(Expression? value, Type type) { ContractUtils.RequiresNotNull(type, nameof(type)); @@ -896,22 +1046,23 @@ public static UnaryExpression Throw(Expression? value, Type type) return new UnaryExpression(ExpressionType.Throw, value!, type, null); } - /// - /// Creates a that represents the incrementing of the expression by 1. - /// - /// An to increment. - /// A that represents the incremented expression. + /// Creates a that represents the incrementing of the expression value by 1. + /// An to increment. + /// A that represents the incremented expression. + /// This expression is functional and does not change the value of the object that is passed to it. + /// The following code example shows how to create an expression that represents an increment operation. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet24"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet24"::: public static UnaryExpression Increment(Expression expression) { return Increment(expression, method: null); } - /// - /// Creates a that represents the incrementing of the expression by 1. - /// - /// An to increment. - /// A that represents the implementing method. - /// A that represents the incremented expression. + /// Creates a that represents the incrementing of the expression by 1. + /// An to increment. + /// A that represents the implementing method. + /// A that represents the incremented expression. + /// This expression is functional and does not change the value of the object that is passed to it. public static UnaryExpression Increment(Expression expression, MethodInfo? method) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -926,22 +1077,23 @@ public static UnaryExpression Increment(Expression expression, MethodInfo? metho return GetMethodBasedUnaryOperator(ExpressionType.Increment, expression, method); } - /// - /// Creates a that represents the decrementing of the expression by 1. - /// - /// An to decrement. - /// A that represents the decremented expression. + /// Creates a that represents the decrementing of the expression by 1. + /// An to decrement. + /// A that represents the decremented expression. + /// This expression is functional and does not change the value of the object passed to it. + /// The following code example shows how to create an expression that subtracts 1 from a given value. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/cs/program.cs" id="Snippet5"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.linq.expressions.expressiondev10/vb/module1.vb" id="Snippet5"::: public static UnaryExpression Decrement(Expression expression) { return Decrement(expression, method: null); } - /// - /// Creates a that represents the decrementing of the expression by 1. - /// - /// An to decrement. - /// A that represents the implementing method. - /// A that represents the decremented expression. + /// Creates a that represents the decrementing of the expression by 1. + /// An to decrement. + /// A that represents the implementing method. + /// A that represents the decremented expression. + /// This expression is functional and does not change the value of the object passed to it. public static UnaryExpression Decrement(Expression expression, MethodInfo? method) { ExpressionUtils.RequiresCanRead(expression, nameof(expression)); @@ -956,93 +1108,69 @@ public static UnaryExpression Decrement(Expression expression, MethodInfo? metho return GetMethodBasedUnaryOperator(ExpressionType.Decrement, expression, method); } - /// - /// Creates a that increments the expression by 1 - /// and assigns the result back to the expression. - /// - /// An to apply the operations on. - /// A that represents the resultant expression. + /// Creates a that increments the expression by 1 and assigns the result back to the expression. + /// An to apply the operations on. + /// A that represents the resultant expression. public static UnaryExpression PreIncrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PreIncrementAssign, expression, method: null); } - /// - /// Creates a that increments the expression by 1 - /// and assigns the result back to the expression. - /// - /// An to apply the operations on. - /// A that represents the implementing method. - /// A that represents the resultant expression. + /// Creates a that increments the expression by 1 and assigns the result back to the expression. + /// An to apply the operations on. + /// A that represents the implementing method. + /// A that represents the resultant expression. public static UnaryExpression PreIncrementAssign(Expression expression, MethodInfo? method) { return MakeOpAssignUnary(ExpressionType.PreIncrementAssign, expression, method); } - /// - /// Creates a that decrements the expression by 1 - /// and assigns the result back to the expression. - /// - /// An to apply the operations on. - /// A that represents the resultant expression. + /// Creates a that decrements the expression by 1 and assigns the result back to the expression. + /// An to apply the operations on. + /// A that represents the resultant expression. public static UnaryExpression PreDecrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PreDecrementAssign, expression, method: null); } - /// - /// Creates a that decrements the expression by 1 - /// and assigns the result back to the expression. - /// - /// An to apply the operations on. - /// A that represents the implementing method. - /// A that represents the resultant expression. + /// Creates a that decrements the expression by 1 and assigns the result back to the expression. + /// An to apply the operations on. + /// A that represents the implementing method. + /// A that represents the resultant expression. public static UnaryExpression PreDecrementAssign(Expression expression, MethodInfo? method) { return MakeOpAssignUnary(ExpressionType.PreDecrementAssign, expression, method); } - /// - /// Creates a that represents the assignment of the expression - /// followed by a subsequent increment by 1 of the original expression. - /// - /// An to apply the operations on. - /// A that represents the resultant expression. + /// Creates a that represents the assignment of the expression followed by a subsequent increment by 1 of the original expression. + /// An to apply the operations on. + /// A that represents the resultant expression. public static UnaryExpression PostIncrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PostIncrementAssign, expression, method: null); } - /// - /// Creates a that represents the assignment of the expression - /// followed by a subsequent increment by 1 of the original expression. - /// - /// An to apply the operations on. - /// A that represents the implementing method. - /// A that represents the resultant expression. + /// Creates a that represents the assignment of the expression followed by a subsequent increment by 1 of the original expression. + /// An to apply the operations on. + /// A that represents the implementing method. + /// A that represents the resultant expression. public static UnaryExpression PostIncrementAssign(Expression expression, MethodInfo? method) { return MakeOpAssignUnary(ExpressionType.PostIncrementAssign, expression, method); } - /// - /// Creates a that represents the assignment of the expression - /// followed by a subsequent decrement by 1 of the original expression. - /// - /// An to apply the operations on. - /// A that represents the resultant expression. + /// Creates a that represents the assignment of the expression followed by a subsequent decrement by 1 of the original expression. + /// An to apply the operations on. + /// A that represents the resultant expression. public static UnaryExpression PostDecrementAssign(Expression expression) { return MakeOpAssignUnary(ExpressionType.PostDecrementAssign, expression, method: null); } - /// - /// Creates a that represents the assignment of the expression - /// followed by a subsequent decrement by 1 of the original expression. - /// - /// An to apply the operations on. - /// A that represents the implementing method. - /// A that represents the resultant expression. + /// Creates a that represents the assignment of the expression followed by a subsequent decrement by 1 of the original expression. + /// An to apply the operations on. + /// A that represents the implementing method. + /// A that represents the resultant expression. public static UnaryExpression PostDecrementAssign(Expression expression, MethodInfo? method) { return MakeOpAssignUnary(ExpressionType.PostDecrementAssign, expression, method); diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/IQueryable.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/IQueryable.cs index ef27dc21d51ba9..de245a0796edaf 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/IQueryable.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/IQueryable.cs @@ -7,99 +7,105 @@ namespace System.Linq { - /// - /// Provides functionality to evaluate queries against a specific data source wherein the type of the data is not specified. - /// + /// Provides functionality to evaluate queries against a specific data source wherein the type of the data is not specified. + /// The interface is intended for implementation by query providers. It is only supposed to be implemented by providers that also implement . If the provider does not also implement , the standard query operators cannot be used on the provider's data source. + /// The interface inherits the interface so that if it represents a query, the results of that query can be enumerated. Enumeration causes the expression tree associated with an object to be executed. The definition of "executing an expression tree" is specific to a query provider. For example, it may involve translating the expression tree to an appropriate query language for the underlying data source. Queries that do not return enumerable results are executed when the method is called. + /// For more information about how to create your own LINQ provider, see LINQ: Building an IQueryable Provider. + /// + /// public interface IQueryable : IEnumerable { - /// - /// Gets the expression tree that is associated with the instance of . - /// + /// Gets the expression tree that is associated with the instance of . + /// The that is associated with this instance of . + /// If an instance of represents a LINQ query against a data source, the associated expression tree represents that query. Expression Expression { get; } - /// - /// Gets the type of the element(s) that are returned when the expression tree associated with this instance of is executed. - /// + /// Gets the type of the element(s) that are returned when the expression tree associated with this instance of is executed. + /// A that represents the type of the element(s) that are returned when the expression tree associated with this object is executed. + /// The property represents the "T" in `IQueryable<T>` or `IQueryable(Of T)`. Type ElementType { get; } - /// - /// Gets the query provider that is associated with this data source. - /// + /// Gets the query provider that is associated with this data source. + /// The that is associated with this data source. + /// If an instance of represents a LINQ query against a data source, the associated query provider is the provider that created the instance. IQueryProvider Provider { get; } } - /// - /// Provides functionality to evaluate queries against a specific data source wherein the type of the data is known. - /// + /// Provides functionality to evaluate queries against a specific data source wherein the type of the data is known. /// The type of the data in the data source. + /// The interface is intended for implementation by query providers. + /// This interface inherits the interface so that if it represents a query, the results of that query can be enumerated. Enumeration forces the expression tree associated with an object to be executed. Queries that do not return enumerable results are executed when the method is called. + /// The definition of "executing an expression tree" is specific to a query provider. For example, it may involve translating the expression tree to a query language appropriate for an underlying data source. + /// The interface enables queries to be polymorphic. That is, because a query against an `IQueryable` data source is represented as an expression tree, it can be executed against different types of data sources. + /// The (`Shared` in Visual Basic) methods defined in the class (except for , , and ) extend objects of types that implement the interface. + /// For more information about how to create your own LINQ provider, see LINQ: Building an IQueryable Provider. + /// public interface IQueryable : IEnumerable, IQueryable { } - /// - /// Defines methods to create and execute queries that are described by an object. - /// - /// - /// The interface is intended for implementation by query providers. - /// + /// Defines methods to create and execute queries that are described by an object. + /// The interface is intended for implementation by query providers. + /// For more information about how to create your own LINQ provider, see LINQ: Building an IQueryable Provider. + /// + /// public interface IQueryProvider { - /// - /// Constructs an object that can evaluate the query represented by a specified expression tree. - /// + /// Constructs an object that can evaluate the query represented by a specified expression tree. /// An expression tree that represents a LINQ query. - /// An that can evaluate the query represented by the specified expression tree. - /// - /// The CreateQuery method is used to create new objects, given an expression tree. The query that is represented by the returned object is associated with a specific LINQ provider. - /// Several of the standard query operator methods defined in Queryable, such as OfType{TResult} and Cast{TResult}, call this method. They pass it a that represents a LINQ query. - /// + /// An that can evaluate the query represented by the specified expression tree. + /// [!NOTE] + /// > The property of the returned object is equal to `expression`. + /// ]]> + /// The method is used to create new objects, given an expression tree. The query that is represented by the returned object is associated with a specific LINQ provider. + /// Several of the standard query operator methods defined in , such as and , call this method. They pass it a that represents a LINQ query. IQueryable CreateQuery(Expression expression); - /// - /// Constructs an object that can evaluate the query represented by a specified expression tree. - /// + /// Constructs an object that can evaluate the query represented by a specified expression tree. + /// The type of the elements of the that is returned. /// An expression tree that represents a LINQ query. - /// An that can evaluate the query represented by the specified expression tree. - /// - /// The method is used to create new objects, given an expression tree. The query that is represented by the returned object is associated with a specific LINQ provider. - /// Most of the Queryable standard query operator methods that return enumerable results call this method.They pass it a that represents a LINQ query. - /// + /// An that can evaluate the query represented by the specified expression tree. + /// [!NOTE] + /// > The property of the returned object is equal to `expression`. + /// ]]> + /// The method is used to create new objects, given an expression tree. The query that is represented by the returned object is associated with a specific LINQ provider. + /// Most of the standard query operator methods that return enumerable results call this method. They pass it a that represents a LINQ query. IQueryable CreateQuery(Expression expression); - /// - /// Executes the query represented by a specified expression tree. - /// + /// Executes the query represented by a specified expression tree. /// An expression tree that represents a LINQ query. /// The value that results from executing the specified query. - /// - /// The method executes queries that return a single value (instead of an enumerable sequence of values). Expression trees that represent queries that return enumerable results are executed when their associated object is enumerated. - /// + /// The method executes queries that return a single value (instead of an enumerable sequence of values). Expression trees that represent queries that return enumerable results are executed when their associated object is enumerated. object? Execute(Expression expression); - /// - /// Executes the strongly-typed query represented by a specified expression tree. - /// + /// Executes the strongly-typed query represented by a specified expression tree. /// The type of the value that results from executing the query. /// An expression tree that represents a LINQ query. /// The value that results from executing the specified query. - /// - /// The method executes queries that return a single value (instead of an enumerable sequence of values). Expression trees that represent queries that return enumerable results are executed when the object that contains the expression tree is enumerated. - /// The Queryable standard query operator methods that return singleton results call . They pass it a that represents a LINQ query. - /// + /// The method executes queries that return a single value (instead of an enumerable sequence of values). Expression trees that represent queries that return enumerable results are executed when the object that contains the expression tree is enumerated. + /// The standard query operator methods that return singleton results call . They pass it a that represents a LINQ query. TResult Execute(Expression expression); } - /// - /// Represents the result of a sorting operation. - /// + /// Represents the result of a sorting operation. + /// The interface is intended for implementation by query providers. + /// This interface represents the result of a sorting query that calls the method(s) , , or . When is called and passed an expression tree that represents a sorting query, the resulting object must be of a type that implements . + /// For more information about how to create your own LINQ provider, see LINQ: Building an IQueryable Provider. + /// + /// public interface IOrderedQueryable : IQueryable { } - /// - /// Represents the result of a sorting operation. - /// + /// Represents the result of a sorting operation. /// The type of the content of the data source. + /// The interface is intended for implementation by query providers. + /// This interface represents the result of a sorting query that calls the method(s) , , or . When is called and passed an expression tree that represents a sorting query, the resulting object must be of a type that implements . + /// For more information about how to create your own LINQ provider, see LINQ: Building an IQueryable Provider. + /// + /// public interface IOrderedQueryable : IQueryable, IOrderedQueryable { } diff --git a/src/libraries/System.Linq.Queryable/src/System/Linq/EnumerableExecutor.cs b/src/libraries/System.Linq.Queryable/src/System/Linq/EnumerableExecutor.cs index 5ff04c6fdcc167..7a8de08fa3eefd 100644 --- a/src/libraries/System.Linq.Queryable/src/System/Linq/EnumerableExecutor.cs +++ b/src/libraries/System.Linq.Queryable/src/System/Linq/EnumerableExecutor.cs @@ -7,11 +7,13 @@ namespace System.Linq { + /// Represents an expression tree and provides functionality to execute the expression tree after rewriting it. public abstract class EnumerableExecutor { [RequiresUnreferencedCode(Queryable.InMemoryQueryableExtensionMethodsRequiresUnreferencedCode)] internal abstract object? ExecuteBoxed(); + /// Initializes a new instance of the class. internal EnumerableExecutor() { } internal static EnumerableExecutor Create(Expression expression) @@ -21,10 +23,14 @@ internal static EnumerableExecutor Create(Expression expression) } } + /// Represents an expression tree and provides functionality to execute the expression tree after rewriting it. + /// The data type of the value that results from executing the expression tree. public class EnumerableExecutor : EnumerableExecutor { private readonly Expression _expression; + /// Initializes a new instance of the class. + /// An expression tree to associate with the new instance. public EnumerableExecutor(Expression expression) { _expression = expression; diff --git a/src/libraries/System.Linq.Queryable/src/System/Linq/EnumerableQuery.cs b/src/libraries/System.Linq.Queryable/src/System/Linq/EnumerableQuery.cs index 3bdd99ea15d07c..718705633389eb 100644 --- a/src/libraries/System.Linq.Queryable/src/System/Linq/EnumerableQuery.cs +++ b/src/libraries/System.Linq.Queryable/src/System/Linq/EnumerableQuery.cs @@ -8,11 +8,13 @@ namespace System.Linq { + /// Represents an as an data source. public abstract class EnumerableQuery { internal abstract Expression Expression { get; } internal abstract IEnumerable? Enumerable { get; } + /// Initializes a new instance of the class. internal EnumerableQuery() { } [RequiresUnreferencedCode(Queryable.InMemoryQueryableExtensionMethodsRequiresUnreferencedCode)] @@ -30,13 +32,20 @@ internal static IQueryable Create(Type elementType, Expression expression) } } + /// Represents an collection as an data source. + /// The type of the data in the collection. public class EnumerableQuery : EnumerableQuery, IOrderedQueryable, IQueryProvider { private readonly Expression _expression; private IEnumerable? _enumerable; + /// Gets the query provider that is associated with this instance. + /// The query provider that is associated with this instance. + /// This member is an explicit interface member implementation. It can be used only when the instance is cast to an interface. IQueryProvider IQueryable.Provider => this; + /// Initializes a new instance of the class and associates it with an collection. + /// A collection to associate with the new instance. [RequiresUnreferencedCode(Queryable.InMemoryQueryableExtensionMethodsRequiresUnreferencedCode)] public EnumerableQuery(IEnumerable enumerable) { @@ -44,6 +53,8 @@ public EnumerableQuery(IEnumerable enumerable) _expression = Expression.Constant(this); } + /// Initializes a new instance of the class and associates the instance with an expression tree. + /// An expression tree to associate with the new instance. [RequiresUnreferencedCode(Queryable.InMemoryQueryableExtensionMethodsRequiresUnreferencedCode)] public EnumerableQuery(Expression expression) { @@ -54,10 +65,19 @@ public EnumerableQuery(Expression expression) internal override IEnumerable? Enumerable => _enumerable; + /// Gets the expression tree that is associated with or that represents this instance. + /// The expression tree that is associated with or that represents this instance. + /// This member is an explicit interface member implementation. It can be used only when the instance is cast to an interface. Expression IQueryable.Expression => _expression; + /// Gets the type of the data in the collection that this instance represents. + /// The type of the data in the collection that this instance represents. + /// This member is an explicit interface member implementation. It can be used only when the instance is cast to an interface. Type IQueryable.ElementType => typeof(T); + /// Constructs a new object and associates it with a specified expression tree that represents an collection of data. + /// An expression tree that represents an collection of data. + /// An object that is associated with . [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This class's ctor is annotated as RequiresUnreferencedCode.")] IQueryable IQueryProvider.CreateQuery(Expression expression) @@ -70,6 +90,10 @@ IQueryable IQueryProvider.CreateQuery(Expression expression) return Create(iqType.GetGenericArguments()[0], expression); } + /// Constructs a new object and associates it with a specified expression tree that represents an collection of data. + /// The type of the data in the collection that represents. + /// An expression tree to execute. + /// An EnumerableQuery object that is associated with . [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This class's ctor is annotated as RequiresUnreferencedCode.")] IQueryable IQueryProvider.CreateQuery(Expression expression) @@ -83,6 +107,9 @@ IQueryable IQueryProvider.CreateQuery(Expression expression) return new EnumerableQuery(expression); } + /// Executes an expression after rewriting it to call methods instead of methods on any enumerable data sources that cannot be queried by methods. + /// An expression tree to execute. + /// The value that results from executing . [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This class's ctor is annotated as RequiresUnreferencedCode.")] object? IQueryProvider.Execute(Expression expression) @@ -92,6 +119,10 @@ IQueryable IQueryProvider.CreateQuery(Expression expression) return EnumerableExecutor.Create(expression).ExecuteBoxed(); } + /// Executes an expression after rewriting it to call methods instead of methods on any enumerable data sources that cannot be queried by methods. + /// The type of the data in the collection that represents. + /// An expression tree to execute. + /// The value that results from executing . [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This class's ctor is annotated as RequiresUnreferencedCode.")] TElement IQueryProvider.Execute(Expression expression) @@ -103,6 +134,9 @@ TElement IQueryProvider.Execute(Expression expression) return new EnumerableExecutor(expression).Execute(); } + /// Returns an enumerator that can iterate through the associated collection, or, if it is null, through the collection that results from rewriting the associated expression tree as a query on an data source and executing it. + /// An enumerator that can be used to iterate through the associated data source. + /// This member is an explicit interface member implementation. It can be used only when the instance is cast to an interface. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); @@ -124,6 +158,8 @@ private IEnumerator GetEnumerator() return _enumerable.GetEnumerator(); } + /// Returns a textual representation of the enumerable collection or, if it is null, of the expression tree that is associated with this instance. + /// A textual representation of the enumerable collection or, if it is null, of the expression tree that is associated with this instance. public override string? ToString() { if (_expression is ConstantExpression c && c.Value == this) diff --git a/src/libraries/System.Linq.Queryable/src/System/Linq/Queryable.cs b/src/libraries/System.Linq.Queryable/src/System/Linq/Queryable.cs index 2917955e9d2695..64ae1c4dcbfe2b 100644 --- a/src/libraries/System.Linq.Queryable/src/System/Linq/Queryable.cs +++ b/src/libraries/System.Linq.Queryable/src/System/Linq/Queryable.cs @@ -8,10 +8,30 @@ namespace System.Linq { + /// Provides a set of ( in Visual Basic) methods for querying data structures that implement . + /// + /// The set of methods declared in the class provides an implementation of the standard query operators for querying data sources that implement . The standard query operators are general purpose methods that follow the LINQ pattern and enable you to express traversal, filter, and projection operations over data in any .NET-based programming language. + /// The majority of the methods in this class are defined as extension methods that extend the type. This means they can be called like an instance method on any object that implements . These methods that extend do not perform any querying directly. Instead, their functionality is to build an object, which is an expression tree that represents the cumulative query. The methods then pass the new expression tree to either the method or the method of the input . The method that is called depends on whether the method returns a singleton value, in which case is called, or has enumerable results, in which case is called. + /// The actual query execution on the target data is performed by a class that implements . The expectation of any implementation is that the result of executing an expression tree that was constructed by a standard query operator method is equivalent to the result of calling the corresponding method in the class, if the data source were an . + /// In addition to the standard query operator methods that operate on objects, this class also contains a method, , which types objects as objects. + /// + /// Language-Integrated Query (LINQ) + /// Standard Query Operators Overview + /// Expression Trees + /// LINQ to SQL public static class Queryable { internal const string InMemoryQueryableExtensionMethodsRequiresUnreferencedCode = "Enumerating in-memory collections as IQueryable can require unreferenced code because expressions referencing IQueryable extension methods can get rebound to IEnumerable extension methods. The IEnumerable extension methods could be trimmed causing the application to fail at runtime."; + /// Converts a generic to a generic . + /// The type of the elements of . + /// A sequence to convert. + /// An that represents the input sequence. + /// is . + /// If the type of implements , returns it directly. Otherwise, it returns an that executes queries by calling the equivalent query operator methods in instead of those in . + /// The following code example demonstrates how to use to convert an to an . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet125"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet125"::: [RequiresUnreferencedCode(InMemoryQueryableExtensionMethodsRequiresUnreferencedCode)] public static IQueryable AsQueryable(this IEnumerable source) { @@ -20,6 +40,15 @@ public static IQueryable AsQueryable(this IEnumerable ?? new EnumerableQuery(source); } + /// Converts an to an . + /// A sequence to convert. + /// An that represents the input sequence. + /// does not implement for some . + /// is . + /// + /// If the type of implements , returns it directly. Otherwise, it returns an that executes queries by calling the equivalent query operator methods in instead of those in . + /// This method assumes that implements for some `T`. At runtime, the result is of type for the same `T`. This method is useful in dynamic scenarios when you do not statically know the type of `T`. + /// [RequiresUnreferencedCode(InMemoryQueryableExtensionMethodsRequiresUnreferencedCode)] public static IQueryable AsQueryable(this IEnumerable source) { @@ -32,6 +61,20 @@ public static IQueryable AsQueryable(this IEnumerable source) return EnumerableQuery.Create(enumType.GenericTypeArguments[0], source); } + /// Filters a sequence of values based on a predicate. + /// The type of the elements of . + /// An to filter. + /// A function to test each element for a condition. + /// An that contains elements from the input sequence that satisfy the condition specified by . + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the elements from that satisfy the condition specified by . + /// + /// The following code example demonstrates how to use to filter a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet110"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet110"::: [DynamicDependency("Where`1", typeof(Enumerable))] public static IQueryable Where(this IQueryable source, Expression> predicate) { @@ -47,6 +90,20 @@ public static IQueryable Where(this IQueryable source )); } + /// Filters a sequence of values based on a predicate. Each element's index is used in the logic of the predicate function. + /// The type of the elements of . + /// An to filter. + /// A function to test each element for a condition; the second parameter of the function represents the index of the element in the source sequence. + /// An that contains elements from the input sequence that satisfy the condition specified by . + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the elements from that satisfy the condition specified by . The index of each source element is provided as the second argument to . + /// + /// The following code example demonstrates how to use to filter a sequence based on a predicate that incorporates the index of each element. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet111"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet111"::: [DynamicDependency("Where`1", typeof(Enumerable))] public static IQueryable Where(this IQueryable source, Expression> predicate) { @@ -62,6 +119,18 @@ public static IQueryable Where(this IQueryable source )); } + /// Filters the elements of an based on a specified type. + /// The type to filter the elements of the sequence on. + /// An whose elements to filter. + /// A collection that contains the elements from that have type . + /// is . + /// + /// The `OfType` method generates a that represents calling `OfType` itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling `OfType` depends on the implementation of the type of the parameter. The expected behavior is that it filters out any elements in that are not of type . + /// + /// The following code example demonstrates how to use `OfType` to filter out elements that are not of type from a list of elements of type . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet69"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet69"::: [DynamicDependency("OfType`1", typeof(Enumerable))] public static IQueryable OfType(this IQueryable source) { @@ -73,6 +142,19 @@ public static IQueryable OfType(this IQueryable source) CachedReflectionInfo.OfType_TResult_1(typeof(TResult)), source.Expression)); } + /// Converts the elements of an to the specified type. + /// The type to convert the elements of to. + /// The that contains the elements to be converted. + /// An that contains each element of the source sequence converted to the specified type. + /// is . + /// An element in the sequence cannot be cast to type . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it converts the values in to type . + /// + /// The following code example demonstrates how to use to convert objects in a sequence to type . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet19"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet19"::: [DynamicDependency("Cast`1", typeof(Enumerable))] public static IQueryable Cast(this IQueryable source) { @@ -84,6 +166,21 @@ public static IQueryable Cast(this IQueryable source) CachedReflectionInfo.Cast_TResult_1(typeof(TResult)), source.Expression)); } + /// Projects each element of a sequence into a new form. + /// The type of the elements of . + /// The type of the value returned by the function represented by . + /// A sequence of values to project. + /// A projection function to apply to each element. + /// An whose elements are the result of invoking a projection function on each element of . + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it invokes on each element of to project it into a different form. + /// + /// The following code example demonstrates how to use to project over a sequence of values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet75"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet75"::: [DynamicDependency("Select`2", typeof(Enumerable))] public static IQueryable Select(this IQueryable source, Expression> selector) { @@ -99,6 +196,21 @@ public static IQueryable Select(this IQueryableProjects each element of a sequence into a new form by incorporating the element's index. + /// The type of the elements of . + /// The type of the value returned by the function represented by . + /// A sequence of values to project. + /// A projection function to apply to each element. + /// An whose elements are the result of invoking a projection function on each element of . + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depend on the implementation of the type of the parameter. The expected behavior is that it invokes on each element of to project it into a different form. + /// + /// The following code example demonstrates how to use to project over a sequence of values and use the index of each element in the projected form. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet76"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet76"::: [DynamicDependency("Select`2", typeof(Enumerable))] public static IQueryable Select(this IQueryable source, Expression> selector) { @@ -114,6 +226,21 @@ public static IQueryable Select(this IQueryableProjects each element of a sequence to an and combines the resulting sequences into one sequence. + /// The type of the elements of . + /// The type of the elements of the sequence returned by the function represented by . + /// A sequence of values to project. + /// A projection function to apply to each element. + /// An whose elements are the result of invoking a one-to-many projection function on each element of the input sequence. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it invokes on each element of to project it into an enumerable form. It then concatenates the enumerable results into a single, one-dimensional sequence. + /// + /// The following code example demonstrates how to use to perform a one-to-many projection over an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet77"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet77"::: [DynamicDependency("SelectMany`2", typeof(Enumerable))] public static IQueryable SelectMany(this IQueryable source, Expression>> selector) { @@ -129,6 +256,21 @@ public static IQueryable SelectMany(this IQueryableProjects each element of a sequence to an and combines the resulting sequences into one sequence. The index of each source element is used in the projected form of that element. + /// The type of the elements of . + /// The type of the elements of the sequence returned by the function represented by . + /// A sequence of values to project. + /// A projection function to apply to each element; the second parameter of this function represents the index of the source element. + /// An whose elements are the result of invoking a one-to-many projection function on each element of the input sequence. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it invokes on each element of to project it into an enumerable form. Each enumerable result incorporates the index of the source element. It then concatenates the enumerable results into a single, one-dimensional sequence. + /// + /// The following code example demonstrates how to use to perform a one-to-many projection over an array and use the index of each source element. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet78"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet78"::: [DynamicDependency("SelectMany`2", typeof(Enumerable))] public static IQueryable SelectMany(this IQueryable source, Expression>> selector) { @@ -144,6 +286,20 @@ public static IQueryable SelectMany(this IQueryableProjects each element of a sequence to an that incorporates the index of the source element that produced it. A result selector function is invoked on each element of each intermediate sequence, and the resulting values are combined into a single, one-dimensional sequence and returned. + /// The type of the elements of . + /// The type of the intermediate elements collected by the function represented by . + /// The type of the elements of the resulting sequence. + /// A sequence of values to project. + /// A projection function to apply to each element of the input sequence; the second parameter of this function represents the index of the source element. + /// A projection function to apply to each element of each intermediate sequence. + /// An whose elements are the result of invoking the one-to-many projection function on each element of and then mapping each of those sequence elements and their corresponding element to a result element. + /// or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it invokes on each element of to project it into an enumerable form. Each enumerable result incorporates the source element's index. Then the function represented by is invoked on each element in each intermediate sequence. The resulting values are concatenated into a single, one-dimensional sequence. + /// [DynamicDependency("SelectMany`3", typeof(Enumerable))] public static IQueryable SelectMany(this IQueryable source, Expression>> collectionSelector, Expression> resultSelector) { @@ -161,6 +317,23 @@ public static IQueryable SelectMany(this )); } + /// Projects each element of a sequence to an and invokes a result selector function on each element therein. The resulting values from each intermediate sequence are combined into a single, one-dimensional sequence and returned. + /// The type of the elements of . + /// The type of the intermediate elements collected by the function represented by . + /// The type of the elements of the resulting sequence. + /// A sequence of values to project. + /// A projection function to apply to each element of the input sequence. + /// A projection function to apply to each element of each intermediate sequence. + /// An whose elements are the result of invoking the one-to-many projection function on each element of and then mapping each of those sequence elements and their corresponding element to a result element. + /// or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it invokes on each element of to project it into an enumerable form. Then the function represented by is invoked on each element in each intermediate sequence. The resulting values are concatenated into a single, one-dimensional sequence. + /// + /// The following code example demonstrates how to use to perform a one-to-many projection over an array. This example uses a result selector function to keep the source element that corresponds to each intermediate sequence in scope for the final call to `Select`. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet124"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet124"::: [DynamicDependency("SelectMany`3", typeof(Enumerable))] public static IQueryable SelectMany(this IQueryable source, Expression>> collectionSelector, Expression> resultSelector) { @@ -184,6 +357,26 @@ private static Expression GetSourceExpression(IEnumerable sour return q != null ? q.Expression : Expression.Constant(source, typeof(IEnumerable)); } + /// Correlates the elements of two sequences based on matching keys. The default equality comparer is used to compare keys. + /// The type of the elements of the first sequence. + /// The type of the elements of the second sequence. + /// The type of the keys returned by the key selector functions. + /// The type of the result elements. + /// The first sequence to join. + /// The sequence to join to the first sequence. + /// A function to extract the join key from each element of the first sequence. + /// A function to extract the join key from each element of the second sequence. + /// A function to create a result element from two matching elements. + /// An that has elements of type obtained by performing an inner join on two sequences. + /// or or or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that of an inner join. The and functions are used to extract keys from and , respectively. These keys are compared for equality to match elements from each sequence. A pair of elements is stored for each element in that matches an element in . Then the function is invoked to project a result object from each pair of matching elements. + /// + /// The following code example demonstrates how to use to perform an inner join of two sequences based on a common key. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet42"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet42"::: [DynamicDependency("Join`4", typeof(Enumerable))] public static IQueryable Join(this IQueryable outer, IEnumerable inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression> resultSelector) { @@ -203,6 +396,24 @@ public static IQueryable Join(this IQuer CachedReflectionInfo.Join_TOuter_TInner_TKey_TResult_5(typeof(TOuter), typeof(TInner), typeof(TKey), typeof(TResult)), outer.Expression, GetSourceExpression(inner), Expression.Quote(outerKeySelector), Expression.Quote(innerKeySelector), Expression.Quote(resultSelector))); } + /// Correlates the elements of two sequences based on matching keys. A specified is used to compare keys. + /// The type of the elements of the first sequence. + /// The type of the elements of the second sequence. + /// The type of the keys returned by the key selector functions. + /// The type of the result elements. + /// The first sequence to join. + /// The sequence to join to the first sequence. + /// A function to extract the join key from each element of the first sequence. + /// A function to extract the join key from each element of the second sequence. + /// A function to create a result element from two matching elements. + /// An to hash and compare keys. + /// An that has elements of type obtained by performing an inner join on two sequences. + /// or or or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that of an inner join. The and functions are used to extract keys from and , respectively. These keys are compared for equality by using . The outcome of the comparisons is used to create a matching pair for each element in that matches an element in . Then the function is invoked to project a result object from each pair of matching elements. + /// [DynamicDependency("Join`4", typeof(Enumerable))] public static IQueryable Join(this IQueryable outer, IEnumerable inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression> resultSelector, IEqualityComparer? comparer) { @@ -222,6 +433,26 @@ public static IQueryable Join(this IQuer CachedReflectionInfo.Join_TOuter_TInner_TKey_TResult_6(typeof(TOuter), typeof(TInner), typeof(TKey), typeof(TResult)), outer.Expression, GetSourceExpression(inner), Expression.Quote(outerKeySelector), Expression.Quote(innerKeySelector), Expression.Quote(resultSelector), Expression.Constant(comparer, typeof(IEqualityComparer)))); } + /// Correlates the elements of two sequences based on key equality and groups the results. The default equality comparer is used to compare keys. + /// The type of the elements of the first sequence. + /// The type of the elements of the second sequence. + /// The type of the keys returned by the key selector functions. + /// The type of the result elements. + /// The first sequence to join. + /// The sequence to join to the first sequence. + /// A function to extract the join key from each element of the first sequence. + /// A function to extract the join key from each element of the second sequence. + /// A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence. + /// An that contains elements of type obtained by performing a grouped join on two sequences. + /// or or or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that the and functions are used to extract keys from and , respectively. These keys are compared for equality to match each element in with zero or more elements from . Then the function is invoked to project a result object from each group of correlated elements. + /// + /// The following code example demonstrates how to use to perform a grouped join on two sequences. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet40"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet40"::: [DynamicDependency("GroupJoin`4", typeof(Enumerable))] public static IQueryable GroupJoin(this IQueryable outer, IEnumerable inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression, TResult>> resultSelector) { @@ -241,6 +472,24 @@ public static IQueryable GroupJoin(this CachedReflectionInfo.GroupJoin_TOuter_TInner_TKey_TResult_5(typeof(TOuter), typeof(TInner), typeof(TKey), typeof(TResult)), outer.Expression, GetSourceExpression(inner), Expression.Quote(outerKeySelector), Expression.Quote(innerKeySelector), Expression.Quote(resultSelector))); } + /// Correlates the elements of two sequences based on key equality and groups the results. A specified is used to compare keys. + /// The type of the elements of the first sequence. + /// The type of the elements of the second sequence. + /// The type of the keys returned by the key selector functions. + /// The type of the result elements. + /// The first sequence to join. + /// The sequence to join to the first sequence. + /// A function to extract the join key from each element of the first sequence. + /// A function to extract the join key from each element of the second sequence. + /// A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence. + /// A comparer to hash and compare keys. + /// An that contains elements of type obtained by performing a grouped join on two sequences. + /// or or or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that the and functions are used to extract keys from and , respectively. These keys are compared for equality by using . The outcome of the comparisons is used to match each element in with zero or more elements from . Then the function is invoked to project a result object from each group of correlated elements. + /// [DynamicDependency("GroupJoin`4", typeof(Enumerable))] public static IQueryable GroupJoin(this IQueryable outer, IEnumerable inner, Expression> outerKeySelector, Expression> innerKeySelector, Expression, TResult>> resultSelector, IEqualityComparer? comparer) { @@ -260,6 +509,21 @@ public static IQueryable GroupJoin(this CachedReflectionInfo.GroupJoin_TOuter_TInner_TKey_TResult_6(typeof(TOuter), typeof(TInner), typeof(TKey), typeof(TResult)), outer.Expression, GetSourceExpression(inner), Expression.Quote(outerKeySelector), Expression.Quote(innerKeySelector), Expression.Quote(resultSelector), Expression.Constant(comparer, typeof(IEqualityComparer)))); } + /// Sorts the elements of a sequence in ascending order according to a key. + /// The type of the elements of . + /// The type of the key returned by the function that is represented by . + /// A sequence of values to order. + /// A function to extract a key from an element. + /// An whose elements are sorted according to a key. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. The result of calling is cast to type and returned. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it sorts the elements of based on the key obtained by invoking on each element of . + /// + /// The following code example demonstrates how to use to sort the elements of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet70"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet70"::: [DynamicDependency("OrderBy`2", typeof(Enumerable))] public static IOrderedQueryable OrderBy(this IQueryable source, Expression> keySelector) { @@ -275,6 +539,19 @@ public static IOrderedQueryable OrderBy(this IQueryable< )); } + /// Sorts the elements of a sequence in ascending order by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by the function that is represented by . + /// A sequence of values to order. + /// A function to extract a key from an element. + /// An to compare keys. + /// An whose elements are sorted according to a key. + /// or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. The result of calling is cast to type and returned. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it sorts the elements of based on the key obtained by invoking on each element of . The parameter is used to compare keys. + /// [DynamicDependency("OrderBy`2", typeof(Enumerable))] public static IOrderedQueryable OrderBy(this IQueryable source, Expression> keySelector, IComparer? comparer) { @@ -290,6 +567,18 @@ public static IOrderedQueryable OrderBy(this IQueryable< )); } + /// Sorts the elements of a sequence in descending order according to a key. + /// The type of the elements of . + /// The type of the key returned by the function that is represented by . + /// A sequence of values to order. + /// A function to extract a key from an element. + /// An whose elements are sorted in descending order according to a key. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. The result of calling is cast to type and returned. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it sorts the elements of in descending order, based on the key obtained by invoking on each element of . + /// [DynamicDependency("OrderByDescending`2", typeof(Enumerable))] public static IOrderedQueryable OrderByDescending(this IQueryable source, Expression> keySelector) { @@ -305,6 +594,22 @@ public static IOrderedQueryable OrderByDescending(this I )); } + /// Sorts the elements of a sequence in descending order by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by the function that is represented by . + /// A sequence of values to order. + /// A function to extract a key from an element. + /// An to compare keys. + /// An whose elements are sorted in descending order according to a key. + /// or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. The result of calling is cast to type and returned. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it sorts the elements of in descending order, based on the key obtained by invoking on each element of . The parameter is used to compare keys. + /// + /// The following code example demonstrates how to use to sort the elements of a sequence in descending order by using a custom comparer. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet71"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet71"::: [DynamicDependency("OrderByDescending`2", typeof(Enumerable))] public static IOrderedQueryable OrderByDescending(this IQueryable source, Expression> keySelector, IComparer? comparer) { @@ -320,6 +625,21 @@ public static IOrderedQueryable OrderByDescending(this I )); } + /// Performs a subsequent ordering of the elements in a sequence in ascending order according to a key. + /// The type of the elements of . + /// The type of the key returned by the function represented by . + /// An that contains elements to sort. + /// A function to extract a key from each element. + /// An whose elements are sorted according to a key. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. The result of calling is cast to type and returned. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it performs a secondary sort of the elements of based on the key obtained by invoking on each element of . All previously established sort orders are preserved. + /// + /// The following code example demonstrates how to use to perform a secondary ordering of the elements in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet102"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet102"::: [DynamicDependency("ThenBy`2", typeof(Enumerable))] public static IOrderedQueryable ThenBy(this IOrderedQueryable source, Expression> keySelector) { @@ -335,6 +655,19 @@ public static IOrderedQueryable ThenBy(this IOrderedQuer )); } + /// Performs a subsequent ordering of the elements in a sequence in ascending order by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by the function represented by . + /// An that contains elements to sort. + /// A function to extract a key from each element. + /// An to compare keys. + /// An whose elements are sorted according to a key. + /// or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. The result of calling is cast to type and returned. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it performs a secondary sort of the elements of based on the key obtained by invoking on each element of . All previously established sort orders are preserved. The parameter is used to compare key values. + /// [DynamicDependency("ThenBy`2", typeof(Enumerable))] public static IOrderedQueryable ThenBy(this IOrderedQueryable source, Expression> keySelector, IComparer? comparer) { @@ -350,6 +683,18 @@ public static IOrderedQueryable ThenBy(this IOrderedQuer )); } + /// Performs a subsequent ordering of the elements in a sequence in descending order, according to a key. + /// The type of the elements of . + /// The type of the key returned by the function represented by . + /// An that contains elements to sort. + /// A function to extract a key from each element. + /// An whose elements are sorted in descending order according to a key. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. The result of calling is cast to type and returned. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it performs a secondary sort of the elements of in descending order, based on the key obtained by invoking on each element of . All previously established sort orders are preserved. + /// [DynamicDependency("ThenByDescending`2", typeof(Enumerable))] public static IOrderedQueryable ThenByDescending(this IOrderedQueryable source, Expression> keySelector) { @@ -365,6 +710,22 @@ public static IOrderedQueryable ThenByDescending(this IO )); } + /// Performs a subsequent ordering of the elements in a sequence in descending order by using a specified comparer. + /// The type of the elements of . + /// The type of the key that is returned by the function. + /// An that contains elements to sort. + /// A function to extract a key from each element. + /// An to compare keys. + /// A collection whose elements are sorted in descending order according to a key. + /// or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. The result of calling is cast to type and returned. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it performs a secondary sort of the elements of in descending order, based on the key obtained by invoking on each element of . All previously established sort orders are preserved. The parameter is used to compare key values. + /// + /// The following code example demonstrates how to use to perform a secondary ordering of the elements in a sequence in descending order by using a custom comparer. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet103"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet103"::: [DynamicDependency("ThenByDescending`2", typeof(Enumerable))] public static IOrderedQueryable ThenByDescending(this IOrderedQueryable source, Expression> keySelector, IComparer? comparer) { @@ -380,6 +741,19 @@ public static IOrderedQueryable ThenByDescending(this IO )); } + /// Returns a specified number of contiguous elements from the start of a sequence. + /// The type of the elements of . + /// The sequence to return elements from. + /// The number of elements to return. + /// An that contains the specified number of elements from the start of . + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it takes the first elements from the start of . + /// + /// The following code example demonstrates how to use to return elements from the start of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet99"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet99"::: [DynamicDependency("Take`1", typeof(Enumerable))] public static IQueryable Take(this IQueryable source, int count) { @@ -394,12 +768,10 @@ public static IQueryable Take(this IQueryable source, } /// Returns a specified range of contiguous elements from a sequence. + /// The type of the elements of . /// The sequence to return elements from. /// The range of elements to return, which has start and end indexes either from the start or the end. - /// The type of the elements of . - /// - /// is . - /// + /// is . /// An that contains the specified of elements from the sequence. [DynamicDependency("Take`1", typeof(Enumerable))] public static IQueryable Take(this IQueryable source, Range range) @@ -414,6 +786,20 @@ public static IQueryable Take(this IQueryable source, )); } + /// Returns elements from a sequence as long as a specified condition is true. + /// The type of the elements of . + /// The sequence to return elements from. + /// A function to test each element for a condition. + /// An that contains elements from the input sequence occurring before the element at which the test specified by no longer passes. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it applies to each element in until it finds an element for which returns . It returns all the elements up until that point. + /// + /// The following code example demonstrates how to use to return elements from the start of a sequence as long as a condition is true. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet100"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet100"::: [DynamicDependency("TakeWhile`1", typeof(Enumerable))] public static IQueryable TakeWhile(this IQueryable source, Expression> predicate) { @@ -429,6 +815,20 @@ public static IQueryable TakeWhile(this IQueryable so )); } + /// Returns elements from a sequence as long as a specified condition is true. The element's index is used in the logic of the predicate function. + /// The type of the elements of . + /// The sequence to return elements from. + /// A function to test each element for a condition; the second parameter of the function represents the index of the element in the source sequence. + /// An that contains elements from the input sequence occurring before the element at which the test specified by no longer passes. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it applies to each element in until it finds an element for which returns . It returns all the elements up until that point. The index of each source element is provided as the second argument to . + /// + /// The following code example demonstrates how to use to return elements from the start of a sequence as long as a condition that uses the index of the element is true. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet101"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet101"::: [DynamicDependency("TakeWhile`1", typeof(Enumerable))] public static IQueryable TakeWhile(this IQueryable source, Expression> predicate) { @@ -444,6 +844,19 @@ public static IQueryable TakeWhile(this IQueryable so )); } + /// Bypasses a specified number of elements in a sequence and then returns the remaining elements. + /// The type of the elements of . + /// An to return elements from. + /// The number of elements to skip before returning the remaining elements. + /// An that contains elements that occur after the specified index in the input sequence. + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it skips the first elements in and returns the remaining elements. + /// + /// The following code example demonstrates how to use to skip a specified number of elements in a sorted array and return the remaining elements. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet87"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet87"::: [DynamicDependency("Skip`1", typeof(Enumerable))] public static IQueryable Skip(this IQueryable source, int count) { @@ -457,6 +870,20 @@ public static IQueryable Skip(this IQueryable source, )); } + /// Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. + /// The type of the elements of . + /// An to return elements from. + /// A function to test each element for a condition. + /// An that contains elements from starting at the first element in the linear series that does not pass the test specified by . + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it applies to each element in until it finds an element for which returns false. That element and all the remaining elements are returned. + /// + /// The following code example demonstrates how to use to skip elements of an array as long as a condition is true. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet88"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet88"::: [DynamicDependency("SkipWhile`1", typeof(Enumerable))] public static IQueryable SkipWhile(this IQueryable source, Expression> predicate) { @@ -472,6 +899,20 @@ public static IQueryable SkipWhile(this IQueryable so )); } + /// Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. The element's index is used in the logic of the predicate function. + /// The type of the elements of . + /// An to return elements from. + /// A function to test each element for a condition; the second parameter of this function represents the index of the source element. + /// An that contains elements from starting at the first element in the linear series that does not pass the test specified by . + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it applies to each element in until it finds an element for which returns false. That element and all the remaining elements are returned. The index of each source element is provided as the second argument to . + /// + /// The following code example demonstrates how to use to skip elements of an array as long as a condition that depends on the element's index is true. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet89"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet89"::: [DynamicDependency("SkipWhile`1", typeof(Enumerable))] public static IQueryable SkipWhile(this IQueryable source, Expression> predicate) { @@ -487,6 +928,21 @@ public static IQueryable SkipWhile(this IQueryable so )); } + /// Groups the elements of a sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of the key returned by the function represented in . + /// An whose elements to group. + /// A function to extract the key for each element. + /// An IQueryable<IGrouping<TKey, TSource>> in C# or IQueryable(Of IGrouping(Of TKey, TSource)) in Visual Basic where each object contains a sequence of objects and a key. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it groups the elements of by a key value that is obtained by invoking on each element. + /// + /// The following code example demonstrates how to use to group the elements of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet14"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet14"::: [DynamicDependency("GroupBy`2", typeof(Enumerable))] public static IQueryable> GroupBy(this IQueryable source, Expression> keySelector) { @@ -502,6 +958,23 @@ public static IQueryable> GroupBy(this I )); } + /// Groups the elements of a sequence according to a specified key selector function and projects the elements for each group by using a specified function. + /// The type of the elements of . + /// The type of the key returned by the function represented in . + /// The type of the elements in each . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to map each source element to an element in an . + /// An IQueryable<IGrouping<TKey, TElement>> in C# or IQueryable(Of IGrouping(Of TKey, TElement)) in Visual Basic where each contains a sequence of objects of type and a key. + /// or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it groups the elements of by a key value that is obtained by invoking on each element. It invokes on each element to obtain a result element. + /// + /// The following code example demonstrates how to use to group the elements of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet39"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet39"::: [DynamicDependency("GroupBy`3", typeof(Enumerable))] public static IQueryable> GroupBy(this IQueryable source, Expression> keySelector, Expression> elementSelector) { @@ -519,6 +992,19 @@ public static IQueryable> GroupByGroups the elements of a sequence according to a specified key selector function and compares the keys by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by the function represented in . + /// An whose elements to group. + /// A function to extract the key for each element. + /// An to compare keys. + /// An IQueryable<IGrouping<TKey, TSource>> in C# or IQueryable(Of IGrouping(Of TKey, TSource)) in Visual Basic where each contains a sequence of objects and a key. + /// or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it groups the elements of by a key value. The key value is obtained by invoking on each element, and key values are compared by using . + /// [DynamicDependency("GroupBy`2", typeof(Enumerable))] public static IQueryable> GroupBy(this IQueryable source, Expression> keySelector, IEqualityComparer? comparer) { @@ -534,6 +1020,21 @@ public static IQueryable> GroupBy(this I )); } + /// Groups the elements of a sequence and projects the elements for each group by using a specified function. Key values are compared by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by the function represented in . + /// The type of the elements in each . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to map each source element to an element in an . + /// An to compare keys. + /// An IQueryable<IGrouping<TKey, TElement>> in C# or IQueryable(Of IGrouping(Of TKey, TElement)) in Visual Basic where each contains a sequence of objects of type and a key. + /// or or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it groups the elements of by a key value that is obtained by invoking on each element. Key values are compared by using . The parameter is invoked on each element to obtain a result element. + /// [DynamicDependency("GroupBy`3", typeof(Enumerable))] public static IQueryable> GroupBy(this IQueryable source, Expression> keySelector, Expression> elementSelector, IEqualityComparer? comparer) { @@ -549,6 +1050,25 @@ public static IQueryable> GroupBy)))); } + /// Groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. The elements of each group are projected by using a specified function. + /// The type of the elements of . + /// The type of the key returned by the function represented in . + /// The type of the elements in each . + /// The type of the result value returned by . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to map each source element to an element in an . + /// A function to create a result value from each group. + /// An T:System.Linq.IQueryable`1 that has a type argument of and where each element represents a projection over a group and its key. + /// or or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it groups the elements of by key values that are obtained by invoking on each element. The parameter is used to project the elements of each group, and the parameter is used to obtain a result value from each group and its key. + /// + /// The following code example demonstrates how to use to group the elements of a sequence and project a sequence of results of type . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet130"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet130"::: [DynamicDependency("GroupBy`4", typeof(Enumerable))] public static IQueryable GroupBy(this IQueryable source, Expression> keySelector, Expression> elementSelector, Expression, TResult>> resultSelector) { @@ -566,6 +1086,23 @@ public static IQueryable GroupBy(this CachedReflectionInfo.GroupBy_TSource_TKey_TElement_TResult_4(typeof(TSource), typeof(TKey), typeof(TElement), typeof(TResult)), source.Expression, Expression.Quote(keySelector), Expression.Quote(elementSelector), Expression.Quote(resultSelector))); } + /// Groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. + /// The type of the elements of . + /// The type of the key returned by the function represented in . + /// The type of the result value returned by . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to create a result value from each group. + /// An T:System.Linq.IQueryable`1 that has a type argument of and where each element represents a projection over a group and its key. + /// or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it groups the elements of by a key value that is obtained by invoking on each element. The parameter is used to obtain a result value from each group and its key. + /// + /// The following code example demonstrates how to use to group the elements of a sequence and project a sequence of results of type . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet15"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet15"::: [DynamicDependency("GroupBy`3", typeof(Enumerable))] public static IQueryable GroupBy(this IQueryable source, Expression> keySelector, Expression, TResult>> resultSelector) { @@ -583,6 +1120,21 @@ public static IQueryable GroupBy(this IQueryabl )); } + /// Groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. Keys are compared by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by the function represented in . + /// The type of the result value returned by . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to create a result value from each group. + /// An to compare keys. + /// An T:System.Linq.IQueryable`1 that has a type argument of and where each element represents a projection over a group and its key. + /// or or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it groups the elements of by key values that are obtained by invoking on each element. The parameter is used to compare keys and the parameter is used to obtain a result value from each group and its key. + /// [DynamicDependency("GroupBy`3", typeof(Enumerable))] public static IQueryable GroupBy(this IQueryable source, Expression> keySelector, Expression, TResult>> resultSelector, IEqualityComparer? comparer) { @@ -598,6 +1150,23 @@ public static IQueryable GroupBy(this IQueryabl CachedReflectionInfo.GroupBy_TSource_TKey_TResult_4(typeof(TSource), typeof(TKey), typeof(TResult)), source.Expression, Expression.Quote(keySelector), Expression.Quote(resultSelector), Expression.Constant(comparer, typeof(IEqualityComparer)))); } + /// Groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. Keys are compared by using a specified comparer and the elements of each group are projected by using a specified function. + /// The type of the elements of . + /// The type of the key returned by the function represented in . + /// The type of the elements in each . + /// The type of the result value returned by . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to map each source element to an element in an . + /// A function to create a result value from each group. + /// An to compare keys. + /// An T:System.Linq.IQueryable`1 that has a type argument of and where each element represents a projection over a group and its key. + /// or or or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it groups the elements of by key values that are obtained by invoking on each element. The parameter is used to compare key values. The parameter is used to project the elements of each group, and the parameter is used to obtain a result value from each group and its key. + /// [DynamicDependency("GroupBy`4", typeof(Enumerable))] public static IQueryable GroupBy(this IQueryable source, Expression> keySelector, Expression> elementSelector, Expression, TResult>> resultSelector, IEqualityComparer? comparer) { @@ -615,6 +1184,18 @@ public static IQueryable GroupBy(this CachedReflectionInfo.GroupBy_TSource_TKey_TElement_TResult_5(typeof(TSource), typeof(TKey), typeof(TElement), typeof(TResult)), source.Expression, Expression.Quote(keySelector), Expression.Quote(elementSelector), Expression.Quote(resultSelector), Expression.Constant(comparer, typeof(IEqualityComparer)))); } + /// Returns distinct elements from a sequence by using the default equality comparer to compare values. + /// The type of the elements of . + /// The to remove duplicates from. + /// An that contains distinct elements from . + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns an unordered sequence of the unique items in . + /// + /// The following code example demonstrates how to use to return distinct elements from a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet27"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet27"::: [DynamicDependency("Distinct`1", typeof(Enumerable))] public static IQueryable Distinct(this IQueryable source) { @@ -626,6 +1207,16 @@ public static IQueryable Distinct(this IQueryable sou CachedReflectionInfo.Distinct_TSource_1(typeof(TSource)), source.Expression)); } + /// Returns distinct elements from a sequence by using a specified to compare values. + /// The type of the elements of . + /// The to remove duplicates from. + /// An to compare values. + /// An that contains distinct elements from . + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns an unordered sequence of the unique items in by using to compare values. + /// [DynamicDependency("Distinct`1", typeof(Enumerable))] public static IQueryable Distinct(this IQueryable source, IEqualityComparer? comparer) { @@ -639,6 +1230,13 @@ public static IQueryable Distinct(this IQueryable sou )); } + /// Returns distinct elements from a sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to distinguish elements by. + /// The sequence to remove duplicate elements from. + /// A function to extract the key for each element. + /// An that contains distinct elements from the source sequence. + /// is . [DynamicDependency("DistinctBy`2", typeof(Enumerable))] public static IQueryable DistinctBy(this IQueryable source, Expression> keySelector) { @@ -654,6 +1252,14 @@ public static IQueryable DistinctBy(this IQueryableReturns distinct elements from a sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to distinguish elements by. + /// The sequence to remove duplicate elements from. + /// A function to extract the key for each element. + /// An to compare keys. + /// An that contains distinct elements from the source sequence. + /// is . [DynamicDependency("DistinctBy`2", typeof(Enumerable))] public static IQueryable DistinctBy(this IQueryable source, Expression> keySelector, IEqualityComparer? comparer) { @@ -669,6 +1275,17 @@ public static IQueryable DistinctBy(this IQueryableSplit the elements of a sequence into chunks of size at most . + /// An whose elements to chunk. + /// Maximum size of each chunk. + /// The type of the elements of source. + /// An that contains the elements the input sequence split into chunks of size . + /// is null. + /// is below 1. + /// + /// Every chunk except the last will be of size . + /// The last chunk will contain the remaining elements and may be of a smaller size. + /// [DynamicDependency("Chunk`1", typeof(Enumerable))] public static IQueryable Chunk(this IQueryable source, int size) { @@ -682,6 +1299,19 @@ public static IQueryable Chunk(this IQueryable sour )); } + /// Concatenates two sequences. + /// The type of the elements of the input sequences. + /// The first sequence to concatenate. + /// The sequence to concatenate to the first sequence. + /// An that contains the concatenated elements of the two input sequences. + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that the elements in are concatenated to those of to create a new sequence. + /// + /// The following code example demonstrates how to use to concatenate two sequences. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet20"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet20"::: [DynamicDependency("Concat`1", typeof(Enumerable))] public static IQueryable Concat(this IQueryable source1, IEnumerable source2) { @@ -697,6 +1327,12 @@ public static IQueryable Concat(this IQueryable sourc )); } + /// Produces a sequence of tuples with elements from the two specified sequences. + /// The type of the elements of the first input sequence. + /// The type of the elements of the second input sequence. + /// The first sequence to merge. + /// The second sequence to merge. + /// A sequence of tuples with elements taken from the first and second sequences, in that order. [DynamicDependency("Zip`2", typeof(Enumerable))] public static IQueryable<(TFirst First, TSecond Second)> Zip(this IQueryable source1, IEnumerable source2) { @@ -717,6 +1353,22 @@ public static IQueryable Concat(this IQueryable sourc source1.Expression, GetSourceExpression(source2))); } + /// Merges two sequences by using the specified predicate function. + /// The type of the elements of the first input sequence. + /// The type of the elements of the second input sequence. + /// The type of the elements of the result sequence. + /// The first sequence to merge. + /// The second sequence to merge. + /// A function that specifies how to merge the elements from the two sequences. + /// An that contains merged elements of two input sequences. + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The method merges each element of the first sequence with an element that has the same index in the second sequence. If the sequences do not have the same number of elements, the method merges sequences until it reaches the end of one of them. For example, if one sequence has three elements and the other one has four, the resulting sequence will have only three elements. + /// + /// The following code example demonstrates how to use the method to merge two sequences. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet200"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet200"::: [DynamicDependency("Zip`3", typeof(Enumerable))] public static IQueryable Zip(this IQueryable source1, IEnumerable source2, Expression> resultSelector) { @@ -761,6 +1413,19 @@ public static IQueryable Zip(this IQueryable< )); } + /// Produces the set union of two sequences by using the default equality comparer. + /// The type of the elements of the input sequences. + /// A sequence whose distinct elements form the first set for the union operation. + /// A sequence whose distinct elements form the second set for the union operation. + /// An that contains the elements from both input sequences, excluding duplicates. + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that the set union of the elements in and is returned. + /// + /// The following code example demonstrates how to use to obtain the set union of two sequences. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet109"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet109"::: [DynamicDependency("Union`1", typeof(Enumerable))] public static IQueryable Union(this IQueryable source1, IEnumerable source2) { @@ -776,6 +1441,17 @@ public static IQueryable Union(this IQueryable source )); } + /// Produces the set union of two sequences by using a specified . + /// The type of the elements of the input sequences. + /// A sequence whose distinct elements form the first set for the union operation. + /// A sequence whose distinct elements form the second set for the union operation. + /// An to compare values. + /// An that contains the elements from both input sequences, excluding duplicates. + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that the set union of the elements in and is returned. The parameter is used to compare values. + /// [DynamicDependency("Union`1", typeof(Enumerable))] public static IQueryable Union(this IQueryable source1, IEnumerable source2, IEqualityComparer? comparer) { @@ -793,6 +1469,14 @@ public static IQueryable Union(this IQueryable source )); } + /// Produces the set union of two sequences according to a specified key selector function. + /// The type of the elements of the input sequences. + /// The type of key to identify elements by. + /// An whose distinct elements form the first set for the union. + /// An whose distinct elements form the second set for the union. + /// A function to extract the key for each element. + /// An that contains the elements from both input sequences, excluding duplicates. + /// or is . [DynamicDependency("UnionBy`2", typeof(Enumerable))] public static IQueryable UnionBy(this IQueryable source1, IEnumerable source2, Expression> keySelector) { @@ -810,6 +1494,15 @@ public static IQueryable UnionBy(this IQueryableProduces the set union of two sequences according to a specified key selector function. + /// The type of the elements of the input sequences. + /// The type of key to identify elements by. + /// An whose distinct elements form the first set for the union. + /// An whose distinct elements form the second set for the union. + /// A function to extract the key for each element. + /// The to compare values. + /// An that contains the elements from both input sequences, excluding duplicates. + /// or is . [DynamicDependency("UnionBy`2", typeof(Enumerable))] public static IQueryable UnionBy(this IQueryable source1, IEnumerable source2, Expression> keySelector, IEqualityComparer? comparer) { @@ -830,6 +1523,19 @@ public static IQueryable UnionBy(this IQueryableProduces the set intersection of two sequences by using the default equality comparer to compare values. + /// The type of the elements of the input sequences. + /// A sequence whose distinct elements that also appear in are returned. + /// A sequence whose distinct elements that also appear in the first sequence are returned. + /// A sequence that contains the set intersection of the two sequences. + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that all the elements in that are also in are returned. + /// + /// The following code example demonstrates how to use to return the elements that appear in each of two sequences. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet41"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet41"::: [DynamicDependency("Intersect`1", typeof(Enumerable))] public static IQueryable Intersect(this IQueryable source1, IEnumerable source2) { @@ -845,6 +1551,17 @@ public static IQueryable Intersect(this IQueryable so )); } + /// Produces the set intersection of two sequences by using the specified to compare values. + /// The type of the elements of the input sequences. + /// An whose distinct elements that also appear in are returned. + /// An whose distinct elements that also appear in the first sequence are returned. + /// An to compare values. + /// An that contains the set intersection of the two sequences. + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that all the elements in that are also in are returned. The parameter is used to compare elements. + /// [DynamicDependency("Intersect`1", typeof(Enumerable))] public static IQueryable Intersect(this IQueryable source1, IEnumerable source2, IEqualityComparer? comparer) { @@ -862,6 +1579,14 @@ public static IQueryable Intersect(this IQueryable so )); } + /// Produces the set intersection of two sequences according to a specified key selector function. + /// The type of the elements of the input sequences. + /// The type of key to identify elements by. + /// An whose distinct elements that also appear in will be returned. + /// An whose distinct elements that also appear in the first sequence will be returned. + /// A function to extract the key for each element. + /// A sequence that contains the elements that form the set intersection of two sequences. + /// or is . [DynamicDependency("IntersectBy`2", typeof(Enumerable))] public static IQueryable IntersectBy(this IQueryable source1, IEnumerable source2, Expression> keySelector) { @@ -881,6 +1606,15 @@ public static IQueryable IntersectBy(this IQueryableProduces the set intersection of two sequences according to a specified key selector function. + /// The type of the elements of the input sequences. + /// The type of key to identify elements by. + /// An whose distinct elements that also appear in will be returned. + /// An whose distinct elements that also appear in the first sequence will be returned. + /// A function to extract the key for each element. + /// An to compare keys. + /// A sequence that contains the elements that form the set intersection of two sequences. + /// or is . [DynamicDependency("IntersectBy`2", typeof(Enumerable))] public static IQueryable IntersectBy(this IQueryable source1, IEnumerable source2, Expression> keySelector, IEqualityComparer? comparer) { @@ -901,6 +1635,19 @@ public static IQueryable IntersectBy(this IQueryableProduces the set difference of two sequences by using the default equality comparer to compare values. + /// The type of the elements of the input sequences. + /// An whose elements that are not also in will be returned. + /// An whose elements that also occur in the first sequence will not appear in the returned sequence. + /// An that contains the set difference of the two sequences. + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that all the elements in are returned except for those that are also in . + /// + /// The following code example demonstrates how to use to return those elements that only appear in the first source sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet34"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet34"::: [DynamicDependency("Except`1", typeof(Enumerable))] public static IQueryable Except(this IQueryable source1, IEnumerable source2) { @@ -916,6 +1663,17 @@ public static IQueryable Except(this IQueryable sourc )); } + /// Produces the set difference of two sequences by using the specified to compare values. + /// The type of the elements of the input sequences. + /// An whose elements that are not also in will be returned. + /// An whose elements that also occur in the first sequence will not appear in the returned sequence. + /// An to compare values. + /// An that contains the set difference of the two sequences. + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that all the elements in are returned except for those that are also in , and is used to compare values. + /// [DynamicDependency("Except`1", typeof(Enumerable))] public static IQueryable Except(this IQueryable source1, IEnumerable source2, IEqualityComparer? comparer) { @@ -972,6 +1730,19 @@ public static IQueryable ExceptBy(this IQueryableReturns the first element of a sequence. + /// The type of the elements of . + /// The to return the first element of. + /// The first element in . + /// is . + /// The source sequence is empty. + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the first element in . + /// + /// The following code example demonstrates how to use to return the first element in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet35"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet35"::: [DynamicDependency("First`1", typeof(Enumerable))] public static TSource First(this IQueryable source) { @@ -983,6 +1754,23 @@ public static TSource First(this IQueryable source) CachedReflectionInfo.First_TSource_1(typeof(TSource)), source.Expression)); } + /// Returns the first element of a sequence that satisfies a specified condition. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// The first element in that passes the test in . + /// or is . + /// No element satisfies the condition in . + /// -or- + /// The source sequence is empty. + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the first element in that satisfies the condition specified by . + /// + /// The following code example demonstrates how to use to return the first element of a sequence that satisfies a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet36"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet36"::: [DynamicDependency("First`1", typeof(Enumerable))] public static TSource First(this IQueryable source, Expression> predicate) { @@ -998,6 +1786,22 @@ public static TSource First(this IQueryable source, Expression )); } + /// Returns the first element of a sequence, or a default value if the sequence contains no elements. + /// The type of the elements of . + /// The to return the first element of. + /// default() if is empty; otherwise, the first element in . + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the first element in , or a default value if is empty. + /// The method does not provide a way to specify the default value to return if is empty. If you want to specify a default value other than `default(TSource)`, use the method as described in the Example section. + /// + /// The following code example demonstrates how to use on an empty sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet37"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet37"::: + /// Sometimes the value of `default(TSource)` is not the default value that you want to use if the collection contains no elements. Instead of checking the result for the unwanted default value and then changing it if necessary, you can use the method to specify the default value that you want to use if the collection is empty. Then, call to obtain the first element. The following code example uses both techniques to obtain a default value of 1 if a collection of numeric months is empty. Because the default value for an integer is 0, which does not correspond to any month, the default value must be specified as 1 instead. The first result variable is checked for the unwanted default value after the query is completed. The second result variable is obtained by calling to specify a default value of 1. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet131"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet131"::: [DynamicDependency("FirstOrDefault`1", typeof(Enumerable))] public static TSource? FirstOrDefault(this IQueryable source) { @@ -1009,6 +1813,12 @@ public static TSource First(this IQueryable source, Expression CachedReflectionInfo.FirstOrDefault_TSource_1(typeof(TSource)), source.Expression)); } + /// Returns the first element of a sequence, or a default value if the sequence contains no elements. + /// The type of the elements of . + /// The to return the first element of. + /// The default value to return if the sequence is empty. + /// if is empty; otherwise, the first element in . + /// is . [DynamicDependency("FirstOrDefault`1", typeof(Enumerable))] public static TSource FirstOrDefault(this IQueryable source, TSource defaultValue) { @@ -1021,6 +1831,20 @@ public static TSource FirstOrDefault(this IQueryable source, T source.Expression, Expression.Constant(defaultValue, typeof(TSource)))); } + /// Returns the first element of a sequence that satisfies a specified condition or a default value if no such element is found. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// default() if is empty or if no element passes the test specified by ; otherwise, the first element in that passes the test specified by . + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the first element in that satisfies the condition in , or a default value if no element satisfies the condition. + /// + /// The following code example demonstrates how to use by passing in a predicate. In the second query, there is no element in the sequence that satisfies the condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet38"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet38"::: [DynamicDependency("FirstOrDefault`1", typeof(Enumerable))] public static TSource? FirstOrDefault(this IQueryable source, Expression> predicate) { @@ -1036,6 +1860,13 @@ public static TSource FirstOrDefault(this IQueryable source, T )); } + /// Returns the first element of the sequence that satisfies a condition or a default value if no such element is found. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// The default value to return if the sequence is empty. + /// if is empty or if no element passes the test specified by ; otherwise, the first element in that passes the test specified by . + /// or is . [DynamicDependency("FirstOrDefault`1", typeof(Enumerable))] public static TSource FirstOrDefault(this IQueryable source, Expression> predicate, TSource defaultValue) { @@ -1051,6 +1882,19 @@ public static TSource FirstOrDefault(this IQueryable source, E )); } + /// Returns the last element in a sequence. + /// The type of the elements of . + /// An to return the last element of. + /// The value at the last position in . + /// is . + /// The source sequence is empty. + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the last element in . + /// + /// The following code example demonstrates how to use to return the last element of an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet43"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet43"::: [DynamicDependency("Last`1", typeof(Enumerable))] public static TSource Last(this IQueryable source) { @@ -1062,6 +1906,23 @@ public static TSource Last(this IQueryable source) CachedReflectionInfo.Last_TSource_1(typeof(TSource)), source.Expression)); } + /// Returns the last element of a sequence that satisfies a specified condition. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// The last element in that passes the test specified by . + /// or is . + /// No element satisfies the condition in . + /// -or- + /// The source sequence is empty. + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the last element in that satisfies the condition specified by . + /// + /// The following code example demonstrates how to use to return the last element of an array that satisfies a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet44"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet44"::: [DynamicDependency("Last`1", typeof(Enumerable))] public static TSource Last(this IQueryable source, Expression> predicate) { @@ -1077,6 +1938,22 @@ public static TSource Last(this IQueryable source, Expression< )); } + /// Returns the last element in a sequence, or a default value if the sequence contains no elements. + /// The type of the elements of . + /// An to return the last element of. + /// default() if is empty; otherwise, the last element in . + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the last element in , or a default value if is empty. + /// The method does not provide a way to specify a default value. If you want to specify a default value other than `default(TSource)`, use the method as described in the Example section. + /// + /// The following code example demonstrates how to use on an empty array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet45"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet45"::: + /// Sometimes the value of `default(TSource)` is not the default value that you want to use if the collection contains no elements. Instead of checking the result for the unwanted default value and then changing it if necessary, you can use the method to specify the default value that you want to use if the collection is empty. Then, call to obtain the last element. The following code example uses both techniques to obtain a default value of 1 if a collection of numeric days of the month is empty. Because the default value for an integer is 0, which does not correspond to any day of the month, the default value must be specified as 1 instead. The first result variable is checked for the unwanted default value after the query is completed. The second result variable is obtained by calling to specify a default value of 1. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet132"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet132"::: [DynamicDependency("LastOrDefault`1", typeof(Enumerable))] public static TSource? LastOrDefault(this IQueryable source) { @@ -1088,6 +1965,12 @@ public static TSource Last(this IQueryable source, Expression< CachedReflectionInfo.LastOrDefault_TSource_1(typeof(TSource)), source.Expression)); } + /// Returns the last element of a sequence, or a default value if the sequence contains no elements. + /// The type of the elements of . + /// An to return the last element of. + /// The default value to return if the sequence is empty. + /// if the source sequence is empty; otherwise, the last element in the . + /// is . [DynamicDependency("LastOrDefault`1", typeof(Enumerable))] public static TSource LastOrDefault(this IQueryable source, TSource defaultValue) { @@ -1100,6 +1983,20 @@ public static TSource LastOrDefault(this IQueryable source, TS source.Expression, Expression.Constant(defaultValue, typeof(TSource)))); } + /// Returns the last element of a sequence that satisfies a condition or a default value if no such element is found. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// default() if is empty or if no elements pass the test in the predicate function; otherwise, the last element of that passes the test in the predicate function. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the last element in that satisfies the condition specified by . It returns a default value if there is no such element in . + /// + /// The following code example demonstrates how to use by passing in a predicate. In the second call to the method, there is no element in the sequence that satisfies the condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet46"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet46"::: [DynamicDependency("LastOrDefault`1", typeof(Enumerable))] public static TSource? LastOrDefault(this IQueryable source, Expression> predicate) { @@ -1115,6 +2012,13 @@ public static TSource LastOrDefault(this IQueryable source, TS )); } + /// Returns the last element of a sequence that satisfies a condition or a default value if no such element is found. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// The default value to return if the sequence is empty. + /// if the sequence is empty or if no elements pass the test in the predicate function; otherwise, the last element that passes the test in the predicate function. + /// or is . [DynamicDependency("LastOrDefault`1", typeof(Enumerable))] public static TSource LastOrDefault(this IQueryable source, Expression> predicate, TSource defaultValue) { @@ -1130,6 +2034,21 @@ public static TSource LastOrDefault(this IQueryable source, Ex )); } + /// Returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence. + /// The type of the elements of . + /// An to return the single element of. + /// The single element of the input sequence. + /// is . + /// has more than one element. + /// -or- + /// The source sequence is empty. + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the only element in . + /// + /// The following code example demonstrates how to use to select the only element of an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet79"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet79"::: [DynamicDependency("Single`1", typeof(Enumerable))] public static TSource Single(this IQueryable source) { @@ -1141,6 +2060,25 @@ public static TSource Single(this IQueryable source) CachedReflectionInfo.Single_TSource_1(typeof(TSource)), source.Expression)); } + /// Returns the only element of a sequence that satisfies a specified condition, and throws an exception if more than one such element exists. + /// The type of the elements of . + /// An to return a single element from. + /// A function to test an element for a condition. + /// The single element of the input sequence that satisfies the condition in . + /// or is . + /// No element satisfies the condition in . + /// -or- + /// More than one element satisfies the condition in . + /// -or- + /// The source sequence is empty. + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the only element in that satisfies the condition specified by . + /// + /// The following code example demonstrates how to use to select the only element of an array that satisfies a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet81"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet81"::: [DynamicDependency("Single`1", typeof(Enumerable))] public static TSource Single(this IQueryable source, Expression> predicate) { @@ -1156,6 +2094,23 @@ public static TSource Single(this IQueryable source, Expressio )); } + /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. + /// The type of the elements of . + /// An to return the single element of. + /// The single element of the input sequence, or default() if the sequence contains no elements. + /// is . + /// has more than one element. + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the only element in , or a default value if is empty. + /// The method does not provide a way to specify a default value. If you want to specify a default value other than `default(TSource)`, use the method as described in the Example section. + /// + /// The following code example demonstrates how to use to select the only element of an array. The second query demonstrates that returns a default value when the sequence does not contain exactly one element. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet83"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet83"::: + /// Sometimes the value of `default(TSource)` is not the default value that you want to use if the collection contains no elements. Instead of checking the result for the unwanted default value and then changing it if necessary, you can use the method to specify the default value that you want to use if the collection is empty. Then, call to obtain the element. The following code example uses both techniques to obtain a default value of 1 if a collection of page numbers is empty. Because the default value for an integer is 0, which is not usually a valid page number, the default value must be specified as 1 instead. The first result variable is checked for the unwanted default value after the query is completed. The second result variable is obtained by calling to specify a default value of 1. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet133"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet133"::: [DynamicDependency("SingleOrDefault`1", typeof(Enumerable))] public static TSource? SingleOrDefault(this IQueryable source) { @@ -1167,6 +2122,13 @@ public static TSource Single(this IQueryable source, Expressio CachedReflectionInfo.SingleOrDefault_TSource_1(typeof(TSource)), source.Expression)); } + /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. + /// The type of the elements of . + /// An to return the single element of. + /// The default value to return if the sequence is empty. + /// The single element of the input sequence, or if the sequence contains no elements. + /// is . + /// The input sequence contains more than one element. [DynamicDependency("SingleOrDefault`1", typeof(Enumerable))] public static TSource SingleOrDefault(this IQueryable source, TSource defaultValue) { @@ -1180,6 +2142,21 @@ public static TSource SingleOrDefault(this IQueryable source, } + /// Returns the only element of a sequence that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. + /// The type of the elements of . + /// An to return a single element from. + /// A function to test an element for a condition. + /// The single element of the input sequence that satisfies the condition in , or default() if no such element is found. + /// or is . + /// More than one element satisfies the condition in . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the only element in that satisfies the condition specified by , or a default value if no such element exists. + /// + /// The following code example demonstrates how to use to select the only element of an array that satisfies a condition. The second query demonstrates that returns a default value when the sequence does not contain exactly one element that satisfies the condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet85"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet85"::: [DynamicDependency("SingleOrDefault`1", typeof(Enumerable))] public static TSource? SingleOrDefault(this IQueryable source, Expression> predicate) { @@ -1195,6 +2172,14 @@ public static TSource SingleOrDefault(this IQueryable source, )); } + /// Returns the only element of a sequence that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. + /// The type of the elements of . + /// An to return a single element from. + /// A function to test an element for a condition. + /// The default value to return if the sequence is empty. + /// The single element of the input sequence that satisfies the condition, or if no such element is found. + /// or is . + /// More than one element satisfies the condition in . [DynamicDependency("SingleOrDefault`1", typeof(Enumerable))] public static TSource SingleOrDefault(this IQueryable source, Expression> predicate, TSource defaultValue) { @@ -1210,6 +2195,20 @@ public static TSource SingleOrDefault(this IQueryable source, )); } + /// Returns the element at a specified index in a sequence. + /// The type of the elements of . + /// An to return an element from. + /// The zero-based index of the element to retrieve. + /// The element at the specified position in . + /// is . + /// is less than zero. + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the item at position in . + /// + /// The following code example demonstrates how to use to return an element at a specific position in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet28"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet28"::: [DynamicDependency("ElementAt`1", typeof(Enumerable))] public static TSource ElementAt(this IQueryable source, int index) { @@ -1226,15 +2225,11 @@ public static TSource ElementAt(this IQueryable source, int in } /// Returns the element at a specified index in a sequence. + /// The type of the elements of . /// An to return an element from. /// The index of the element to retrieve, which is either from the start or the end. - /// The type of the elements of . - /// - /// is . - /// - /// - /// is outside the bounds of the sequence. - /// + /// is . + /// is outside the bounds of the sequence. /// The element at the specified position in the sequence. [DynamicDependency("ElementAt`1", typeof(Enumerable))] public static TSource ElementAt(this IQueryable source, Index index) @@ -1251,6 +2246,19 @@ public static TSource ElementAt(this IQueryable source, Index )); } + /// Returns the element at a specified index in a sequence or a default value if the index is out of range. + /// The type of the elements of . + /// An to return an element from. + /// The zero-based index of the element to retrieve. + /// default() if is outside the bounds of ; otherwise, the element at the specified position in . + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the item at position in , or `default(TSource)` if is outside the bounds of . + /// + /// The following code example demonstrates how to use . This example uses a value for that is outside the bounds of the source sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet29"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet29"::: [DynamicDependency("ElementAtOrDefault`1", typeof(Enumerable))] public static TSource? ElementAtOrDefault(this IQueryable source, int index) { @@ -1265,15 +2273,11 @@ public static TSource ElementAt(this IQueryable source, Index } /// Returns the element at a specified index in a sequence or a default value if the index is out of range. + /// The type of the elements of . /// An to return an element from. /// The index of the element to retrieve, which is either from the start or the end. - /// The type of the elements of . - /// - /// is . - /// - /// - /// if index is outside the bounds of the sequence; otherwise, the element at the specified position in the sequence. - /// + /// is . + /// if is outside the bounds of the sequence; otherwise, the element at the specified position in the sequence. [DynamicDependency("ElementAtOrDefault`1", typeof(Enumerable))] public static TSource? ElementAtOrDefault(this IQueryable source, Index index) { @@ -1287,6 +2291,18 @@ public static TSource ElementAt(this IQueryable source, Index )); } + /// Returns the elements of the specified sequence or the type parameter's default value in a singleton collection if the sequence is empty. + /// The type of the elements of . + /// The to return a default value for if empty. + /// An that contains () if is empty; otherwise, . + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns if it is not empty. Otherwise, it returns an that contains `default(TSource)`. + /// + /// The following code examples demonstrate how to use to provide a default value in case the source sequence is empty. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet24"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet24"::: [DynamicDependency("DefaultIfEmpty`1", typeof(Enumerable))] public static IQueryable DefaultIfEmpty(this IQueryable source) { @@ -1298,6 +2314,19 @@ public static IQueryable DefaultIfEmpty(this IQueryableReturns the elements of the specified sequence or the specified value in a singleton collection if the sequence is empty. + /// The type of the elements of . + /// The to return the specified value for if empty. + /// The value to return if the sequence is empty. + /// An that contains if is empty; otherwise, . + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns if it is not empty. Otherwise, it returns an that contains . + /// + /// The following code example shows a situation in which it is useful to call in a LINQ query. A default value is passed to in this example. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet25"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet25"::: [DynamicDependency("DefaultIfEmpty`1", typeof(Enumerable))] public static IQueryable DefaultIfEmpty(this IQueryable source, TSource defaultValue) { @@ -1311,6 +2340,19 @@ public static IQueryable DefaultIfEmpty(this IQueryableDetermines whether a sequence contains a specified element by using the default equality comparer. + /// The type of the elements of . + /// An in which to locate . + /// The object to locate in the sequence. + /// if the input sequence contains an element that has the specified value; otherwise, . + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it determines if contains . + /// + /// The following code example demonstrates how to use to determine whether a sequence contains a specific element. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet21"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet21"::: [DynamicDependency("Contains`1", typeof(Enumerable))] public static bool Contains(this IQueryable source, TSource item) { @@ -1324,6 +2366,17 @@ public static bool Contains(this IQueryable source, TSource it )); } + /// Determines whether a sequence contains a specified element by using a specified . + /// The type of the elements of . + /// An in which to locate . + /// The object to locate in the sequence. + /// An to compare values. + /// if the input sequence contains an element that has the specified value; otherwise, . + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it determines if contains by using to compare values. + /// [DynamicDependency("Contains`1", typeof(Enumerable))] public static bool Contains(this IQueryable source, TSource item, IEqualityComparer? comparer) { @@ -1337,6 +2390,18 @@ public static bool Contains(this IQueryable source, TSource it )); } + /// Inverts the order of the elements in a sequence. + /// The type of the elements of . + /// A sequence of values to reverse. + /// An whose elements correspond to those of the input sequence in reverse order. + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it reverses the order of the elements in . + /// + /// The following code example demonstrates how to use to reverse the order of elements in an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet74"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet74"::: [DynamicDependency("Reverse`1", typeof(Enumerable))] public static IQueryable Reverse(this IQueryable source) { @@ -1348,6 +2413,22 @@ public static IQueryable Reverse(this IQueryable sour CachedReflectionInfo.Reverse_TSource_1(typeof(TSource)), source.Expression)); } + /// Determines whether two sequences are equal by using the default equality comparer to compare elements. + /// The type of the elements of the input sequences. + /// An whose elements to compare to those of . + /// An whose elements to compare to those of the first sequence. + /// if the two source sequences are of equal length and their corresponding elements compare equal; otherwise, . + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it determines if the two source sequences are equal. + /// + /// The following code example demonstrates how to use to determine whether two sequences are equal. In this example the sequences are equal. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet32"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet32"::: + /// The following code example compares two sequences that are not equal. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet33"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet33"::: [DynamicDependency("SequenceEqual`1", typeof(Enumerable))] public static bool SequenceEqual(this IQueryable source1, IEnumerable source2) { @@ -1363,6 +2444,17 @@ public static bool SequenceEqual(this IQueryable source1, IEnu )); } + /// Determines whether two sequences are equal by using a specified to compare elements. + /// The type of the elements of the input sequences. + /// An whose elements to compare to those of . + /// An whose elements to compare to those of the first sequence. + /// An to use to compare elements. + /// if the two source sequences are of equal length and their corresponding elements compare equal; otherwise, . + /// or is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it determines if the two source sequences are equal by using to compare elements. + /// [DynamicDependency("SequenceEqual`1", typeof(Enumerable))] public static bool SequenceEqual(this IQueryable source1, IEnumerable source2, IEqualityComparer? comparer) { @@ -1380,6 +2472,21 @@ public static bool SequenceEqual(this IQueryable source1, IEnu )); } + /// Determines whether a sequence contains any elements. + /// The type of the elements of . + /// A sequence to check for being empty. + /// if the source sequence contains any elements; otherwise, . + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it determines if contains any elements. + /// + /// The following code example demonstrates how to use to determine whether a sequence contains any elements. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet5"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet5"::: + /// The Boolean value that the method returns is typically used in the predicate of a `where` clause (`Where` clause in Visual Basic) or a direct call to the method. The following example demonstrates this use of the `Any` method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet135"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet135"::: [DynamicDependency("Any`1", typeof(Enumerable))] public static bool Any(this IQueryable source) { @@ -1391,6 +2498,20 @@ public static bool Any(this IQueryable source) CachedReflectionInfo.Any_TSource_1(typeof(TSource)), source.Expression)); } + /// Determines whether any element of a sequence satisfies a condition. + /// The type of the elements of . + /// A sequence whose elements to test for a condition. + /// A function to test each element for a condition. + /// if any elements in the source sequence pass the test in the specified predicate; otherwise, . + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it determines if any of the elements of satisfy the condition specified by . + /// + /// The following code example demonstrates how to use to determine whether any element in a sequence satisfies a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet6"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet6"::: [DynamicDependency("Any`1", typeof(Enumerable))] public static bool Any(this IQueryable source, Expression> predicate) { @@ -1406,6 +2527,23 @@ public static bool Any(this IQueryable source, ExpressionDetermines whether all the elements of a sequence satisfy a condition. + /// The type of the elements of . + /// A sequence whose elements to test for a condition. + /// A function to test each element for a condition. + /// if every element of the source sequence passes the test in the specified predicate, or if the sequence is empty; otherwise, . + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the parameter's type. The expected behavior is that it determines if all the elements in satisfy the condition in . + /// + /// The following code example demonstrates how to use to determine whether all the elements in a sequence satisfy a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet4"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet4"::: + /// The Boolean value that the method returns is typically used in the predicate of a `where` clause (`Where` clause in Visual Basic) or a direct call to the method. The following example demonstrates this use of the `All` method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet134"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet134"::: [DynamicDependency("All`1", typeof(Enumerable))] public static bool All(this IQueryable source, Expression> predicate) { @@ -1421,6 +2559,19 @@ public static bool All(this IQueryable source, ExpressionReturns the number of elements in a sequence. + /// The type of the elements of . + /// The that contains the elements to be counted. + /// The number of elements in the input sequence. + /// is . + /// The number of elements in is larger than . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it counts the number of items in . + /// + /// The following code example demonstrates how to use to count the elements in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet22"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet22"::: [DynamicDependency("Count`1", typeof(Enumerable))] public static int Count(this IQueryable source) { @@ -1432,6 +2583,21 @@ public static int Count(this IQueryable source) CachedReflectionInfo.Count_TSource_1(typeof(TSource)), source.Expression)); } + /// Returns the number of elements in the specified sequence that satisfies a condition. + /// The type of the elements of . + /// An that contains the elements to be counted. + /// A function to test each element for a condition. + /// The number of elements in the sequence that satisfies the condition in the predicate function. + /// or is . + /// The number of elements in is larger than . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it counts the number of items in that satisfy the condition specified by . + /// + /// The following code example demonstrates how to use to count the elements in a sequence that satisfy a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet23"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet23"::: [DynamicDependency("Count`1", typeof(Enumerable))] public static int Count(this IQueryable source, Expression> predicate) { @@ -1447,6 +2613,19 @@ public static int Count(this IQueryable source, ExpressionReturns an that represents the total number of elements in a sequence. + /// The type of the elements of . + /// An that contains the elements to be counted. + /// The number of elements in . + /// is . + /// The number of elements exceeds . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it counts the number of items in and returns an . + /// + /// The following code example demonstrates how to use to count the elements in an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet47"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet47"::: [DynamicDependency("LongCount`1", typeof(Enumerable))] public static long LongCount(this IQueryable source) { @@ -1458,6 +2637,21 @@ public static long LongCount(this IQueryable source) CachedReflectionInfo.LongCount_TSource_1(typeof(TSource)), source.Expression)); } + /// Returns an that represents the number of elements in a sequence that satisfy a condition. + /// The type of the elements of . + /// An that contains the elements to be counted. + /// A function to test each element for a condition. + /// The number of elements in that satisfy the condition in the predicate function. + /// or is . + /// The number of matching elements exceeds . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it counts the number of items in that satisfy the condition specified by and returns an . + /// + /// The following code example demonstrates how to use to count the elements in an array that satisfy a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet48"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet48"::: [DynamicDependency("LongCount`1", typeof(Enumerable))] public static long LongCount(this IQueryable source, Expression> predicate) { @@ -1473,6 +2667,19 @@ public static long LongCount(this IQueryable source, Expressio )); } + /// Returns the minimum value of a generic . + /// The type of the elements of . + /// A sequence of values to determine the minimum of. + /// The minimum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the minimum value in . + /// + /// The following code example demonstrates how to use to determine the minimum value in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet60"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet60"::: [DynamicDependency("Min`1", typeof(Enumerable))] public static TSource? Min(this IQueryable source) { @@ -1484,6 +2691,13 @@ public static long LongCount(this IQueryable source, Expressio CachedReflectionInfo.Min_TSource_1(typeof(TSource)), source.Expression)); } + /// Returns the minimum value in a generic . + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// The to compare values. + /// The minimum value in the sequence. + /// is . + /// No object in implements the or interface. [DynamicDependency("Min`1", typeof(Enumerable))] public static TSource? Min(this IQueryable source, IComparer? comparer) { @@ -1498,6 +2712,22 @@ public static long LongCount(this IQueryable source, Expressio )); } + /// Invokes a projection function on each element of a generic and returns the minimum resulting value. + /// The type of the elements of . + /// The type of the value returned by the function represented by . + /// A sequence of values to determine the minimum of. + /// A projection function to apply to each element. + /// The minimum value in the sequence. + /// or is . + /// contains no elements. + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it invokes on each element in and returns the minimum value. + /// + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet68"::: [DynamicDependency("Min`2", typeof(Enumerable))] public static TResult? Min(this IQueryable source, Expression> selector) { @@ -1513,6 +2743,14 @@ public static long LongCount(this IQueryable source, Expressio )); } + /// Returns the minimum value in a generic according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the minimum value of. + /// A function to extract the key for each element. + /// The value with the minimum key in the sequence. + /// is . + /// No key extracted from implements the or interface. [DynamicDependency("MinBy`2", typeof(Enumerable))] public static TSource? MinBy(this IQueryable source, Expression> keySelector) { @@ -1529,6 +2767,15 @@ public static long LongCount(this IQueryable source, Expressio )); } + /// Returns the minimum value in a generic according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the minimum value of. + /// A function to extract the key for each element. + /// The to compare keys. + /// The value with the minimum key in the sequence. + /// is . + /// No key extracted from implements the or interface. [DynamicDependency("MinBy`2", typeof(Enumerable))] public static TSource? MinBy(this IQueryable source, Expression> keySelector, IComparer? comparer) { @@ -1546,6 +2793,19 @@ public static long LongCount(this IQueryable source, Expressio )); } + /// Returns the maximum value in a generic . + /// The type of the elements of . + /// A sequence of values to determine the maximum of. + /// The maximum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the maximum value in . + /// + /// The following code example demonstrates how to use to determine the maximum value in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet52"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet52"::: [DynamicDependency("Max`1", typeof(Enumerable))] public static TSource? Max(this IQueryable source) { @@ -1556,7 +2816,12 @@ public static long LongCount(this IQueryable source, Expressio null, CachedReflectionInfo.Max_TSource_1(typeof(TSource)), source.Expression)); } - + /// Returns the maximum value in a generic . + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// The to compare values. + /// The maximum value in the sequence. + /// is . [DynamicDependency("Max`1", typeof(Enumerable))] public static TSource? Max(this IQueryable source, IComparer? comparer) { @@ -1571,6 +2836,22 @@ public static long LongCount(this IQueryable source, Expressio )); } + /// Invokes a projection function on each element of a generic and returns the maximum resulting value. + /// The type of the elements of . + /// The type of the value returned by the function represented by . + /// A sequence of values to determine the maximum of. + /// A projection function to apply to each element. + /// The maximum value in the sequence. + /// or is . + /// contains no elements. + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it invokes on each element in and returns the maximum value. + /// + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet58"::: [DynamicDependency("Max`2", typeof(Enumerable))] public static TResult? Max(this IQueryable source, Expression> selector) { @@ -1586,6 +2867,14 @@ public static long LongCount(this IQueryable source, Expressio )); } + /// Returns the maximum value in a generic according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the maximum value of. + /// A function to extract the key for each element. + /// The value with the maximum key in the sequence. + /// is . + /// No key extracted from implements the or interface. [DynamicDependency("MaxBy`2", typeof(Enumerable))] public static TSource? MaxBy(this IQueryable source, Expression> keySelector) { @@ -1602,6 +2891,15 @@ public static long LongCount(this IQueryable source, Expressio )); } + /// Returns the maximum value in a generic according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the maximum value of. + /// A function to extract the key for each element. + /// The to compare keys. + /// The value with the maximum key in the sequence. + /// is . + /// No key extracted from implements the or interface. [DynamicDependency("MaxBy`2", typeof(Enumerable))] public static TSource? MaxBy(this IQueryable source, Expression> keySelector, IComparer? comparer) { @@ -1619,6 +2917,15 @@ public static long LongCount(this IQueryable source, Expressio )); } + /// Computes the sum of a sequence of values. + /// A sequence of values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the sum of the values in . + /// [DynamicDependency("Sum", typeof(Enumerable))] public static int Sum(this IQueryable source) { @@ -1630,6 +2937,15 @@ public static int Sum(this IQueryable source) CachedReflectionInfo.Sum_Int32_1, source.Expression)); } + /// Computes the sum of a sequence of nullable values. + /// A sequence of nullable values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the sum of the values in . + /// [DynamicDependency("Sum", typeof(Enumerable))] public static int? Sum(this IQueryable source) { @@ -1641,6 +2957,15 @@ public static int Sum(this IQueryable source) CachedReflectionInfo.Sum_NullableInt32_1, source.Expression)); } + /// Computes the sum of a sequence of values. + /// A sequence of values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the sum of the values in . + /// [DynamicDependency("Sum", typeof(Enumerable))] public static long Sum(this IQueryable source) { @@ -1652,6 +2977,15 @@ public static long Sum(this IQueryable source) CachedReflectionInfo.Sum_Int64_1, source.Expression)); } + /// Computes the sum of a sequence of nullable values. + /// A sequence of nullable values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the sum of the values in . + /// [DynamicDependency("Sum", typeof(Enumerable))] public static long? Sum(this IQueryable source) { @@ -1663,6 +2997,17 @@ public static long Sum(this IQueryable source) CachedReflectionInfo.Sum_NullableInt64_1, source.Expression)); } + /// Computes the sum of a sequence of values. + /// A sequence of values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the sum of the values in . + /// + /// The following code example demonstrates how to use to sum the values of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet120"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet120"::: [DynamicDependency("Sum", typeof(Enumerable))] public static float Sum(this IQueryable source) { @@ -1674,6 +3019,17 @@ public static float Sum(this IQueryable source) CachedReflectionInfo.Sum_Single_1, source.Expression)); } + /// Computes the sum of a sequence of nullable values. + /// A sequence of nullable values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the sum of the values in . + /// + /// The following code example demonstrates how to use to sum the values of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet121"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet121"::: [DynamicDependency("Sum", typeof(Enumerable))] public static float? Sum(this IQueryable source) { @@ -1685,6 +3041,14 @@ public static float Sum(this IQueryable source) CachedReflectionInfo.Sum_NullableSingle_1, source.Expression)); } + /// Computes the sum of a sequence of values. + /// A sequence of values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the sum of the values in . + /// [DynamicDependency("Sum", typeof(Enumerable))] public static double Sum(this IQueryable source) { @@ -1696,6 +3060,14 @@ public static double Sum(this IQueryable source) CachedReflectionInfo.Sum_Double_1, source.Expression)); } + /// Computes the sum of a sequence of nullable values. + /// A sequence of nullable values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the sum of the values in . + /// [DynamicDependency("Sum", typeof(Enumerable))] public static double? Sum(this IQueryable source) { @@ -1707,6 +3079,15 @@ public static double Sum(this IQueryable source) CachedReflectionInfo.Sum_NullableDouble_1, source.Expression)); } + /// Computes the sum of a sequence of values. + /// A sequence of values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the sum of the values in . + /// [DynamicDependency("Sum", typeof(Enumerable))] public static decimal Sum(this IQueryable source) { @@ -1718,6 +3099,15 @@ public static decimal Sum(this IQueryable source) CachedReflectionInfo.Sum_Decimal_1, source.Expression)); } + /// Computes the sum of a sequence of nullable values. + /// A sequence of nullable values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it returns the sum of the values in . + /// [DynamicDependency("Sum", typeof(Enumerable))] public static decimal? Sum(this IQueryable source) { @@ -1729,6 +3119,23 @@ public static decimal Sum(this IQueryable source) CachedReflectionInfo.Sum_NullableDecimal_1, source.Expression)); } + /// Computes the sum of the sequence of values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values of type . + /// A projection function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it invokes `selector` on each element of `source` and returns the sum of the resulting values. + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet98"::: + /// ]]> [DynamicDependency("Sum`1", typeof(Enumerable))] public static int Sum(this IQueryable source, Expression> selector) { @@ -1744,6 +3151,23 @@ public static int Sum(this IQueryable source, ExpressionComputes the sum of the sequence of nullable values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values of type . + /// A projection function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it invokes `selector` on each element of `source` and returns the sum of the resulting values. + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet98"::: + /// ]]> [DynamicDependency("Sum`1", typeof(Enumerable))] public static int? Sum(this IQueryable source, Expression> selector) { @@ -1759,6 +3183,23 @@ public static int Sum(this IQueryable source, ExpressionComputes the sum of the sequence of values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values of type . + /// A projection function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it invokes `selector` on each element of `source` and returns the sum of the resulting values. + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet98"::: + /// ]]> [DynamicDependency("Sum`1", typeof(Enumerable))] public static long Sum(this IQueryable source, Expression> selector) { @@ -1774,6 +3215,23 @@ public static long Sum(this IQueryable source, ExpressionComputes the sum of the sequence of nullable values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values of type . + /// A projection function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it invokes `selector` on each element of `source` and returns the sum of the resulting values. + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet98"::: + /// ]]> [DynamicDependency("Sum`1", typeof(Enumerable))] public static long? Sum(this IQueryable source, Expression> selector) { @@ -1789,6 +3247,22 @@ public static long Sum(this IQueryable source, ExpressionComputes the sum of the sequence of values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values of type . + /// A projection function to apply to each element. + /// The sum of the projected values. + /// or is . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it invokes `selector` on each element of `source` and returns the sum of the resulting values. + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet98"::: + /// ]]> [DynamicDependency("Sum`1", typeof(Enumerable))] public static float Sum(this IQueryable source, Expression> selector) { @@ -1804,6 +3278,22 @@ public static float Sum(this IQueryable source, ExpressionComputes the sum of the sequence of nullable values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values of type . + /// A projection function to apply to each element. + /// The sum of the projected values. + /// or is . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it invokes `selector` on each element of `source` and returns the sum of the resulting values. + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet98"::: + /// ]]> [DynamicDependency("Sum`1", typeof(Enumerable))] public static float? Sum(this IQueryable source, Expression> selector) { @@ -1819,6 +3309,22 @@ public static float Sum(this IQueryable source, ExpressionComputes the sum of the sequence of values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values of type . + /// A projection function to apply to each element. + /// The sum of the projected values. + /// or is . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of he `source` parameter. The expected behavior is that it invokes `selector` on each element of `source` and returns the sum of the resulting values. + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet98"::: + /// ]]> [DynamicDependency("Sum`1", typeof(Enumerable))] public static double Sum(this IQueryable source, Expression> selector) { @@ -1834,6 +3340,22 @@ public static double Sum(this IQueryable source, ExpressionComputes the sum of the sequence of nullable values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values of type . + /// A projection function to apply to each element. + /// The sum of the projected values. + /// or is . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it invokes `selector` on each element of `source` and returns the sum of the resulting values. + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet98"::: + /// ]]> [DynamicDependency("Sum`1", typeof(Enumerable))] public static double? Sum(this IQueryable source, Expression> selector) { @@ -1849,6 +3371,23 @@ public static double Sum(this IQueryable source, ExpressionComputes the sum of the sequence of values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values of type . + /// A projection function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it invokes `selector` on each element of `source` and returns the sum of the resulting values. + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet98"::: + /// ]]> [DynamicDependency("Sum`1", typeof(Enumerable))] public static decimal Sum(this IQueryable source, Expression> selector) { @@ -1864,6 +3403,23 @@ public static decimal Sum(this IQueryable source, ExpressionComputes the sum of the sequence of nullable values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values of type . + /// A projection function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it invokes `selector` on each element of `source` and returns the sum of the resulting values. + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet98"::: + /// ]]> [DynamicDependency("Sum`1", typeof(Enumerable))] public static decimal? Sum(this IQueryable source, Expression> selector) { @@ -1879,6 +3435,18 @@ public static decimal Sum(this IQueryable source, ExpressionComputes the average of a sequence of values. + /// A sequence of values to calculate the average of. + /// The average of the sequence of values. + /// is . + /// contains no elements. + /// + /// The method generates a that represents calling itself. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it calculates the average of the values in . + /// + /// The following code example demonstrates how to use to calculate the average of a sequence of values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet8"::: [DynamicDependency("Average", typeof(Enumerable))] public static double Average(this IQueryable source) { @@ -1890,6 +3458,19 @@ public static double Average(this IQueryable source) CachedReflectionInfo.Average_Int32_1, source.Expression)); } + /// Computes the average of a sequence of nullable values. + /// A sequence of nullable values to calculate the average of. + /// The average of the sequence of values, or if the source sequence is empty or contains only values. + /// is . + /// method generates a that represents calling itself. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source`. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average of a sequence of values. + /// [!INCLUDE[sqo_diff_overload_example_elementtype](~/includes/sqo-diff-overload-example-elementtype-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet12"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet12"::: + /// ]]> [DynamicDependency("Average", typeof(Enumerable))] public static double? Average(this IQueryable source) { @@ -1901,6 +3482,20 @@ public static double Average(this IQueryable source) CachedReflectionInfo.Average_NullableInt32_1, source.Expression)); } + /// Computes the average of a sequence of values. + /// A sequence of values to calculate the average of. + /// The average of the sequence of values. + /// is . + /// contains no elements. + /// method generates a that represents calling itself. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source`. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average of a sequence of values. + /// [!INCLUDE[sqo_diff_overload_example_elementtype](~/includes/sqo-diff-overload-example-elementtype-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet8"::: + /// ]]> [DynamicDependency("Average", typeof(Enumerable))] public static double Average(this IQueryable source) { @@ -1912,6 +3507,17 @@ public static double Average(this IQueryable source) CachedReflectionInfo.Average_Int64_1, source.Expression)); } + /// Computes the average of a sequence of nullable values. + /// A sequence of nullable values to calculate the average of. + /// The average of the sequence of values, or if the source sequence is empty or contains only values. + /// is . + /// + /// The method generates a that represents calling itself. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it calculates the average of the values in . + /// + /// The following code example demonstrates how to use to calculate the average of a sequence of values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet12"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet12"::: [DynamicDependency("Average", typeof(Enumerable))] public static double? Average(this IQueryable source) { @@ -1923,6 +3529,20 @@ public static double Average(this IQueryable source) CachedReflectionInfo.Average_NullableInt64_1, source.Expression)); } + /// Computes the average of a sequence of values. + /// A sequence of values to calculate the average of. + /// The average of the sequence of values. + /// is . + /// contains no elements. + /// method generates a that represents calling itself. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source`. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average of a sequence of values. + /// [!INCLUDE[sqo_diff_overload_example_elementtype](~/includes/sqo-diff-overload-example-elementtype-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet8"::: + /// ]]> [DynamicDependency("Average", typeof(Enumerable))] public static float Average(this IQueryable source) { @@ -1934,6 +3554,19 @@ public static float Average(this IQueryable source) CachedReflectionInfo.Average_Single_1, source.Expression)); } + /// Computes the average of a sequence of nullable values. + /// A sequence of nullable values to calculate the average of. + /// The average of the sequence of values, or if the source sequence is empty or contains only values. + /// is . + /// method generates a that represents calling itself. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source`. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average of a sequence of values. + /// [!INCLUDE[sqo_diff_overload_example_elementtype](~/includes/sqo-diff-overload-example-elementtype-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet12"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet12"::: + /// ]]> [DynamicDependency("Average", typeof(Enumerable))] public static float? Average(this IQueryable source) { @@ -1945,6 +3578,20 @@ public static float Average(this IQueryable source) CachedReflectionInfo.Average_NullableSingle_1, source.Expression)); } + /// Computes the average of a sequence of values. + /// A sequence of values to calculate the average of. + /// The average of the sequence of values. + /// is . + /// contains no elements. + /// method generates a that represents calling itself. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source`. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average of a sequence of values. + /// [!INCLUDE[sqo_diff_overload_example_elementtype](~/includes/sqo-diff-overload-example-elementtype-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet8"::: + /// ]]> [DynamicDependency("Average", typeof(Enumerable))] public static double Average(this IQueryable source) { @@ -1956,6 +3603,19 @@ public static double Average(this IQueryable source) CachedReflectionInfo.Average_Double_1, source.Expression)); } + /// Computes the average of a sequence of nullable values. + /// A sequence of nullable values to calculate the average of. + /// The average of the sequence of values, or if the source sequence is empty or contains only values. + /// is . + /// method generates a that represents calling itself. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source`. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average of a sequence of values. + /// [!INCLUDE[sqo_diff_overload_example_elementtype](~/includes/sqo-diff-overload-example-elementtype-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet12"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet12"::: + /// ]]> [DynamicDependency("Average", typeof(Enumerable))] public static double? Average(this IQueryable source) { @@ -1967,6 +3627,20 @@ public static double Average(this IQueryable source) CachedReflectionInfo.Average_NullableDouble_1, source.Expression)); } + /// Computes the average of a sequence of values. + /// A sequence of values to calculate the average of. + /// The average of the sequence of values. + /// is . + /// contains no elements. + /// method generates a that represents calling itself. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source`. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average of a sequence of values. + /// [!INCLUDE[sqo_diff_overload_example_elementtype](~/includes/sqo-diff-overload-example-elementtype-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet8"::: + /// ]]> [DynamicDependency("Average", typeof(Enumerable))] public static decimal Average(this IQueryable source) { @@ -1978,6 +3652,19 @@ public static decimal Average(this IQueryable source) CachedReflectionInfo.Average_Decimal_1, source.Expression)); } + /// Computes the average of a sequence of nullable values. + /// A sequence of nullable values to calculate the average of. + /// The average of the sequence of values, or if the source sequence is empty or contains only values. + /// is . + /// method generates a that represents calling itself. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source`. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average of a sequence of values. + /// [!INCLUDE[sqo_diff_overload_example_elementtype](~/includes/sqo-diff-overload-example-elementtype-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet12"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet12"::: + /// ]]> [DynamicDependency("Average", typeof(Enumerable))] public static decimal? Average(this IQueryable source) { @@ -1989,6 +3676,21 @@ public static decimal Average(this IQueryable source) CachedReflectionInfo.Average_NullableDecimal_1, source.Expression)); } + /// Computes the average of a sequence of values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A projection function to apply to each element. + /// The average of the sequence of values. + /// or is . + /// contains no elements. + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that it calculates the average of the values in after invoking on each value. + /// + /// The following code example demonstrates how to use to calculate the average length in a sequence of values of type . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet18"::: [DynamicDependency("Average`1", typeof(Enumerable))] public static double Average(this IQueryable source, Expression> selector) { @@ -2004,6 +3706,22 @@ public static double Average(this IQueryable source, Expressio )); } + /// Computes the average of a sequence of nullable values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A projection function to apply to each element. + /// The average of the sequence of values, or if the sequence is empty or contains only values. + /// or is . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source` after invoking `selector` on each value. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average length in a sequence of values of type . + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet18"::: + /// ]]> [DynamicDependency("Average`1", typeof(Enumerable))] public static double? Average(this IQueryable source, Expression> selector) { @@ -2019,6 +3737,23 @@ public static double Average(this IQueryable source, Expressio )); } + /// Computes the average of a sequence of values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A projection function to apply to each element. + /// The average of the sequence of values. + /// or is . + /// contains no elements. + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source` after invoking `selector` on each value. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average length in a sequence of values of type . + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet18"::: + /// ]]> [DynamicDependency("Average`1", typeof(Enumerable))] public static float Average(this IQueryable source, Expression> selector) { @@ -2034,6 +3769,22 @@ public static float Average(this IQueryable source, Expression )); } + /// Computes the average of a sequence of nullable values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A projection function to apply to each element. + /// The average of the sequence of values, or if the sequence is empty or contains only values. + /// or is . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source` after invoking `selector` on each value. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average length in a sequence of values of type . + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet18"::: + /// ]]> [DynamicDependency("Average`1", typeof(Enumerable))] public static float? Average(this IQueryable source, Expression> selector) { @@ -2049,6 +3800,23 @@ public static float Average(this IQueryable source, Expression )); } + /// Computes the average of a sequence of values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A projection function to apply to each element. + /// The average of the sequence of values. + /// or is . + /// contains no elements. + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source` after invoking `selector` on each value. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average length in a sequence of values of type . + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet18"::: + /// ]]> [DynamicDependency("Average`1", typeof(Enumerable))] public static double Average(this IQueryable source, Expression> selector) { @@ -2064,6 +3832,22 @@ public static double Average(this IQueryable source, Expressio )); } + /// Computes the average of a sequence of nullable values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A projection function to apply to each element. + /// The average of the sequence of values, or if the sequence is empty or contains only values. + /// or is . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source` after invoking `selector` on each value. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average length in a sequence of values of type . + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet18"::: + /// ]]> [DynamicDependency("Average`1", typeof(Enumerable))] public static double? Average(this IQueryable source, Expression> selector) { @@ -2079,6 +3863,23 @@ public static double Average(this IQueryable source, Expressio )); } + /// Computes the average of a sequence of values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A projection function to apply to each element. + /// The average of the sequence of values. + /// or is . + /// contains no elements. + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source` after invoking `selector` on each value. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average length in a sequence of values of type . + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet18"::: + /// ]]> [DynamicDependency("Average`1", typeof(Enumerable))] public static double Average(this IQueryable source, Expression> selector) { @@ -2094,6 +3895,22 @@ public static double Average(this IQueryable source, Expressio )); } + /// Computes the average of a sequence of nullable values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A projection function to apply to each element. + /// The average of the sequence of values, or if the sequence is empty or contains only values. + /// or is . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source` after invoking `selector` on each value. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average length in a sequence of values of type . + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet18"::: + /// ]]> [DynamicDependency("Average`1", typeof(Enumerable))] public static double? Average(this IQueryable source, Expression> selector) { @@ -2109,6 +3926,23 @@ public static double Average(this IQueryable source, Expressio )); } + /// Computes the average of a sequence of values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate an average. + /// A projection function to apply to each element. + /// The average of the sequence of values. + /// or is . + /// contains no elements. + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source` after invoking `selector` on each value. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average length in a sequence of values of type . + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet18"::: + /// ]]> [DynamicDependency("Average`1", typeof(Enumerable))] public static decimal Average(this IQueryable source, Expression> selector) { @@ -2124,6 +3958,22 @@ public static decimal Average(this IQueryable source, Expressi )); } + /// Computes the average of a sequence of nullable values that is obtained by invoking a projection function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A projection function to apply to each element. + /// The average of the sequence of values, or if the sequence is empty or contains only values. + /// or is . + /// whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the `source` parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the `source` parameter. The expected behavior is that it calculates the average of the values in `source` after invoking `selector` on each value. + /// ## Examples + /// The following code example demonstrates how to use to calculate the average length in a sequence of values of type . + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet18"::: + /// ]]> [DynamicDependency("Average`1", typeof(Enumerable))] public static decimal? Average(this IQueryable source, Expression> selector) { @@ -2139,6 +3989,22 @@ public static decimal Average(this IQueryable source, Expressi )); } + /// Applies an accumulator function over a sequence. + /// The type of the elements of . + /// A sequence to aggregate over. + /// An accumulator function to apply to each element. + /// The final accumulator value. + /// or is . + /// contains no elements. + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that the specified function, , is applied to each value in the source sequence and the accumulated value is returned. The first value in is used as the seed value for the accumulated value, which corresponds to the first parameter in . + /// To simplify common aggregation operations, the set of standard query operators also includes two counting methods, and , and four numeric aggregation methods, namely , , , and . + /// + /// The following code example demonstrates how to use to build a sentence from an array of strings. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet1"::: [DynamicDependency("Aggregate`1", typeof(Enumerable))] public static TSource Aggregate(this IQueryable source, Expression> func) { @@ -2154,6 +4020,23 @@ public static TSource Aggregate(this IQueryable source, Expres )); } + /// Applies an accumulator function over a sequence. The specified seed value is used as the initial accumulator value. + /// The type of the elements of . + /// The type of the accumulator value. + /// A sequence to aggregate over. + /// The initial accumulator value. + /// An accumulator function to invoke on each element. + /// The final accumulator value. + /// or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that the specified function, , is applied to each value in the source sequence and the accumulated value is returned. The parameter is used as the seed value for the accumulated value, which corresponds to the first parameter in . + /// To simplify common aggregation operations, the set of standard query operators also includes two counting methods, and , and four numeric aggregation methods, namely , , , and . + /// + /// The following code example demonstrates how to use to apply an accumulator function when a seed value is provided to the function. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet2"::: [DynamicDependency("Aggregate`2", typeof(Enumerable))] public static TAccumulate Aggregate(this IQueryable source, TAccumulate seed, Expression> func) { @@ -2169,6 +4052,25 @@ public static TAccumulate Aggregate(this IQueryableApplies an accumulator function over a sequence. The specified seed value is used as the initial accumulator value, and the specified function is used to select the result value. + /// The type of the elements of . + /// The type of the accumulator value. + /// The type of the resulting value. + /// A sequence to aggregate over. + /// The initial accumulator value. + /// An accumulator function to invoke on each element. + /// A function to transform the final accumulator value into the result value. + /// The transformed final accumulator value. + /// or or is . + /// + /// This method has at least one parameter of type whose type argument is one of the types. For these parameters, you can pass in a lambda expression and it will be compiled to an . + /// The method generates a that represents calling itself as a constructed generic method. It then passes the to the method of the represented by the property of the parameter. + /// The query behavior that occurs as a result of executing an expression tree that represents calling depends on the implementation of the type of the parameter. The expected behavior is that the specified function, , is applied to each value in the source sequence and the accumulated value is returned. The parameter is used as the seed value for the accumulated value, which corresponds to the first parameter in . The final accumulated value is passed to to obtain the result value. + /// To simplify common aggregation operations, the set of standard query operators also includes two counting methods, and , and four numeric aggregation methods, namely , , , and . + /// + /// The following code example demonstrates how to use to apply an accumulator function and a result selector. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Queryable/CS/queryable.cs" interactive="try-dotnet-method" id="Snippet3"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Queryable/VB/queryable.vb" id="Snippet3"::: [DynamicDependency("Aggregate`3", typeof(Enumerable))] public static TResult Aggregate(this IQueryable source, TAccumulate seed, Expression> func, Expression> selector) { @@ -2184,6 +4086,13 @@ public static TResult Aggregate(this IQueryableReturns a new queryable sequence that contains the elements from with the last elements of the source queryable sequence omitted. + /// The type of the elements in the queryable sequence. + /// A queryable sequence. + /// The number of elements to omit from the end of the queryable sequence. + /// A new queryable sequence that contains the elements from minus elements from the end of the queryable sequence. + /// is . + /// If is not a positive number, this method returns an identical copy of the queryable sequence. [DynamicDependency("SkipLast`1", typeof(Enumerable))] public static IQueryable SkipLast(this IQueryable source, int count) { @@ -2197,6 +4106,13 @@ public static IQueryable SkipLast(this IQueryable sou )); } + /// Returns a new queryable sequence that contains the last elements from . + /// The type of the elements in the queryable sequence. + /// A queryable sequence instance. + /// The number of elements to take from the end of the queryable sequence. + /// A new queryable sequence that contains the last elements from . + /// is . + /// If is not a positive number, this method returns an empty queryable sequence. [DynamicDependency("TakeLast`1", typeof(Enumerable))] public static IQueryable TakeLast(this IQueryable source, int count) { @@ -2210,6 +4126,12 @@ public static IQueryable TakeLast(this IQueryable sou )); } + /// Returns a new queryable sequence that contains the elements from plus the specified appended at the end. + /// The type of the elements in the queryable sequence. + /// A queryable sequence. + /// An element of type to append to . + /// A new queryable sequence that contains the elements from plus the specified appended at the end. + /// is . [DynamicDependency("Append`1", typeof(Enumerable))] public static IQueryable Append(this IQueryable source, TSource element) { @@ -2223,6 +4145,12 @@ public static IQueryable Append(this IQueryable sourc )); } + /// Returns a new queryable sequence that contains the elements from plus the specified prepended at the beginning. + /// The type of the elements in the queryable sequence. + /// A queryable sequence. + /// An element of type to prepend to . + /// A new queryable sequence that contains the elements from plus the specified prepended at the beginning. + /// is . [DynamicDependency("Prepend`1", typeof(Enumerable))] public static IQueryable Prepend(this IQueryable source, TSource element) { diff --git a/src/libraries/System.Linq/src/System/Linq/Aggregate.cs b/src/libraries/System.Linq/src/System/Linq/Aggregate.cs index 81c3c0aa9a9c80..43bfb3a0038b2b 100644 --- a/src/libraries/System.Linq/src/System/Linq/Aggregate.cs +++ b/src/libraries/System.Linq/src/System/Linq/Aggregate.cs @@ -7,6 +7,37 @@ namespace System.Linq { public static partial class Enumerable { + /// Applies an accumulator function over a sequence. + /// The type of the elements of . + /// An to aggregate over. + /// An accumulator function to be invoked on each element. + /// The final accumulator value. + /// or is . + /// contains no elements. + /// + /// + /// The method makes it simple to perform a calculation over a sequence of values. + /// This method works by calling one time for each element in except the first one. + /// Each time is called, passes both the element from + /// the sequence and an aggregated value (as the first argument to ). The first element of + /// is used as the initial aggregate value. The result of replaces the previous aggregated value. + /// returns the final result of . + /// + /// + /// This overload of the method isn't suitable for all cases because it uses the first element of + /// as the initial aggregate value. You should choose another overload if the return value should include only the + /// elements of that meet a certain condition. For example, this overload isn't reliable if you want to calculate + /// the sum of the even numbers in . The result will be incorrect if the first element is odd instead of even. + /// + /// + /// To simplify common aggregation operations, the standard query operators also include a general purpose count method, , + /// and four numeric aggregation methods, namely , , , + /// and + /// . + /// + /// The following code example demonstrates how to reverse the order of words in a string by using . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet1"::: public static TSource Aggregate(this IEnumerable source, Func func) { if (source == null) @@ -36,6 +67,32 @@ public static TSource Aggregate(this IEnumerable source, Func< } } + /// Applies an accumulator function over a sequence. The specified seed value is used as the initial accumulator value. + /// The type of the elements of . + /// The type of the accumulator value. + /// An to aggregate over. + /// The initial accumulator value. + /// An accumulator function to be invoked on each element. + /// The final accumulator value. + /// or is . + /// + /// + /// The method makes it simple to perform a calculation over a sequence of values. + /// This method works by calling one time for each element in . Each time + /// is called, passes both the element from the sequence and an aggregated value + /// (as the first argument to ). The value of the parameter is used as the initial aggregate value. + /// The result of replaces the previous aggregated value. + /// returns the final result of . + /// + /// + /// To simplify common aggregation operations, the standard query operators also include a general purpose count method, , + /// and four numeric aggregation methods, namely , , , + /// and . + /// + /// + /// The following code example demonstrates how to use to apply an accumulator function and use a seed value. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet2"::: public static TAccumulate Aggregate(this IEnumerable source, TAccumulate seed, Func func) { if (source == null) @@ -57,6 +114,37 @@ public static TAccumulate Aggregate(this IEnumerable + /// Applies an accumulator function over a sequence. The specified seed value is used as the initial accumulator value, + /// and the specified function is used to select the result value. + /// + /// The type of the elements of . + /// The type of the accumulator value. + /// The type of the resulting value. + /// An to aggregate over. + /// The initial accumulator value. + /// An accumulator function to be invoked on each element. + /// A function to transform the final accumulator value into the result value. + /// The transformed final accumulator value. + /// or or is . + /// + /// + /// The method makes it simple to perform a calculation over a sequence of values. + /// This method works by calling one time for each element in . Each time is called, + /// passes both the element from the sequence and an aggregated value + /// (as the first argument to ). The value of the parameter is used as the initial aggregate value. + /// The result of replaces the previous aggregated value. The final result of is passed to + /// to obtain the final result of . + /// + /// + /// To simplify common aggregation operations, the standard query operators also include a general purpose count method, , + /// and four numeric aggregation methods, namely , , , + /// and . + /// + /// + /// The following code example demonstrates how to use to apply an accumulator function and a result selector. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet3"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet3"::: public static TResult Aggregate(this IEnumerable source, TAccumulate seed, Func func, Func resultSelector) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/AnyAll.cs b/src/libraries/System.Linq/src/System/Linq/AnyAll.cs index eff7af66721f34..83190f00fb530f 100644 --- a/src/libraries/System.Linq/src/System/Linq/AnyAll.cs +++ b/src/libraries/System.Linq/src/System/Linq/AnyAll.cs @@ -8,6 +8,26 @@ namespace System.Linq { public static partial class Enumerable { + /// Determines whether a sequence contains any elements. + /// The type of the elements of . + /// The to check for emptiness. + /// if the source sequence contains any elements; otherwise, . + /// is . + /// [!NOTE] + /// > This method does not return any one element of a collection. Instead, it determines whether the collection contains any elements. + /// ]]> + /// The enumeration of is stopped as soon as the result can be determined. + /// In Visual Basic query expression syntax, an `Aggregate Into Any()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine whether a sequence contains any elements. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet5"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet5"::: + /// The Boolean value that the method returns is typically used in the predicate of a `where` clause (`Where` clause in Visual Basic) or a direct call to the method. The following example demonstrates this use of the `Any` method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet130"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet130"::: + /// + /// Aggregate Clause (Visual Basic) public static bool Any(this IEnumerable source) { if (source == null) @@ -44,6 +64,23 @@ public static bool Any(this IEnumerable source) } } + /// Determines whether any element of a sequence satisfies a condition. + /// The type of the elements of . + /// An whose elements to apply the predicate to. + /// A function to test each element for a condition. + /// if the source sequence is not empty and at least one of its elements passes the test in the specified predicate; otherwise, . + /// or is . + /// [!NOTE] + /// > This method does not return any one element of a collection. Instead, it determines whether any elements of a collection satisfy a condition. + /// ]]> + /// The enumeration of is stopped as soon as the result can be determined. + /// In Visual Basic query expression syntax, an `Aggregate Into Any()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine whether any element in a sequence satisfies a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet6"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet6"::: + /// Aggregate Clause (Visual Basic) public static bool Any(this IEnumerable source, Func predicate) { if (source == null) @@ -67,6 +104,26 @@ public static bool Any(this IEnumerable source, FuncDetermines whether all elements of a sequence satisfy a condition. + /// The type of the elements of . + /// An that contains the elements to apply the predicate to. + /// A function to test each element for a condition. + /// if every element of the source sequence passes the test in the specified predicate, or if the sequence is empty; otherwise, . + /// or is . + /// [!NOTE] + /// > This method does not return all the elements of a collection. Instead, it determines whether all the elements of a collection satisfy a condition. + /// ]]> + /// The enumeration of is stopped as soon as the result can be determined. + /// In Visual Basic query expression syntax, an `Aggregate Into All()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine whether all the elements in a sequence satisfy a condition. Variable `allStartWithB` is true if all the pet names start with "B" or if the `pets` array is empty. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet4"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet4"::: + /// The Boolean value that the method returns is typically used in the predicate of a `where` clause (`Where` clause in Visual Basic) or a direct call to the method. The following example demonstrates this use of the `All` method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet129"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet129"::: + /// Aggregate Clause (Visual Basic) public static bool All(this IEnumerable source, Func predicate) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/AppendPrepend.cs b/src/libraries/System.Linq/src/System/Linq/AppendPrepend.cs index 2397fbd39e2828..21561f6dcaa7a9 100644 --- a/src/libraries/System.Linq/src/System/Linq/AppendPrepend.cs +++ b/src/libraries/System.Linq/src/System/Linq/AppendPrepend.cs @@ -8,6 +8,19 @@ namespace System.Linq { public static partial class Enumerable { + /// Appends a value to the end of the sequence. + /// The type of the elements of . + /// A sequence of values. + /// The value to append to . + /// A new sequence that ends with . + /// is . + /// [!NOTE] + /// > This method does not modify the elements of the collection. Instead, it creates a copy of the collection with the new element. + /// ]]> + /// The following code example demonstrates how to use to append a value to the end of the sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet201"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet201"::: public static IEnumerable Append(this IEnumerable source, TSource element) { if (source == null) @@ -20,6 +33,19 @@ public static IEnumerable Append(this IEnumerable sou : new AppendPrepend1Iterator(source, element, appending: true); } + /// Adds a value to the beginning of the sequence. + /// The type of the elements of . + /// A sequence of values. + /// The value to prepend to . + /// A new sequence that begins with . + /// is . + /// [!NOTE] + /// > This method does not modify the elements of the collection. Instead, it creates a copy of the collection with the new element. + /// ]]> + /// The following code example demonstrates how to use to prepend a value to the beginning of the sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet202"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet202"::: public static IEnumerable Prepend(this IEnumerable source, TSource element) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Average.cs b/src/libraries/System.Linq/src/System/Linq/Average.cs index e204d87cb6159c..d49108b9b4a533 100644 --- a/src/libraries/System.Linq/src/System/Linq/Average.cs +++ b/src/libraries/System.Linq/src/System/Linq/Average.cs @@ -7,6 +7,16 @@ namespace System.Linq { public static partial class Enumerable { + /// Computes the average of a sequence of values. + /// A sequence of values to calculate the average of. + /// The average of the sequence of values. + /// is . + /// contains no elements. + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// The following code example demonstrates how to use to calculate an average. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet8"::: + /// Aggregate Clause (Visual Basic) public static double Average(this IEnumerable source) { if (source == null) @@ -36,6 +46,13 @@ public static double Average(this IEnumerable source) } } + /// Computes the average of a sequence of nullable values. + /// A sequence of nullable values to calculate the average of. + /// The average of the sequence of values, or if the source sequence is empty or contains only values that are . + /// is . + /// The sum of the elements in the sequence is larger than . + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// Aggregate Clause (Visual Basic) public static double? Average(this IEnumerable source) { if (source == null) @@ -73,6 +90,13 @@ public static double Average(this IEnumerable source) return null; } + /// Computes the average of a sequence of values. + /// A sequence of values to calculate the average of. + /// The average of the sequence of values. + /// is . + /// contains no elements. + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// Aggregate Clause (Visual Basic) public static double Average(this IEnumerable source) { if (source == null) @@ -102,6 +126,16 @@ public static double Average(this IEnumerable source) } } + /// Computes the average of a sequence of nullable values. + /// A sequence of nullable values to calculate the average of. + /// The average of the sequence of values, or if the source sequence is empty or contains only values that are . + /// is . + /// The sum of the elements in the sequence is larger than . + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// The following code example demonstrates how to use to calculate an average. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet12"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet12"::: + /// Aggregate Clause (Visual Basic) public static double? Average(this IEnumerable source) { if (source == null) @@ -139,6 +173,13 @@ public static double Average(this IEnumerable source) return null; } + /// Computes the average of a sequence of values. + /// A sequence of values to calculate the average of. + /// The average of the sequence of values. + /// is . + /// contains no elements. + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// Aggregate Clause (Visual Basic) public static float Average(this IEnumerable source) { if (source == null) @@ -165,6 +206,12 @@ public static float Average(this IEnumerable source) } } + /// Computes the average of a sequence of nullable values. + /// A sequence of nullable values to calculate the average of. + /// The average of the sequence of values, or if the source sequence is empty or contains only values that are . + /// is . + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// Aggregate Clause (Visual Basic) public static float? Average(this IEnumerable source) { if (source == null) @@ -202,6 +249,16 @@ public static float Average(this IEnumerable source) return null; } + /// Computes the average of a sequence of values. + /// A sequence of values to calculate the average of. + /// The average of the sequence of values. + /// is . + /// contains no elements. + /// + /// If the sum of the elements is too large to represent as a , this method returns positive or negative infinity. + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static double Average(this IEnumerable source) { if (source == null) @@ -231,6 +288,15 @@ public static double Average(this IEnumerable source) } } + /// Computes the average of a sequence of nullable values. + /// A sequence of nullable values to calculate the average of. + /// The average of the sequence of values, or if the source sequence is empty or contains only values that are . + /// is . + /// + ///If the sum of the elements is too large to represent as a , this method returns positive or negative infinity. + ///In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static double? Average(this IEnumerable source) { if (source == null) @@ -268,6 +334,13 @@ public static double Average(this IEnumerable source) return null; } + /// Computes the average of a sequence of values. + /// A sequence of values to calculate the average of. + /// The average of the sequence of values. + /// is . + /// contains no elements. + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// Aggregate Clause (Visual Basic) public static decimal Average(this IEnumerable source) { if (source == null) @@ -294,6 +367,13 @@ public static decimal Average(this IEnumerable source) } } + /// Computes the average of a sequence of nullable values. + /// A sequence of nullable values to calculate the average of. + /// The average of the sequence of values, or if the source sequence is empty or contains only values that are . + /// is . + /// The sum of the elements in the sequence is larger than . + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// Aggregate Clause (Visual Basic) public static decimal? Average(this IEnumerable source) { if (source == null) @@ -328,6 +408,19 @@ public static decimal Average(this IEnumerable source) return null; } + /// Computes the average of a sequence of values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A transform function to apply to each element. + /// The average of the sequence of values. + /// or is . + /// contains no elements. + /// The sum of the elements in the sequence is larger than . + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// The following code example demonstrates how to use to calculate an average. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet18"::: + /// Aggregate Clause (Visual Basic) public static double Average(this IEnumerable source, Func selector) { if (source == null) @@ -362,6 +455,22 @@ public static double Average(this IEnumerable source, FuncComputes the average of a sequence of nullable values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A transform function to apply to each element. + /// The average of the sequence of values, or if the source sequence is empty or contains only values that are . + /// or is . + /// The sum of the elements in the sequence is larger than . + /// . + /// ## Examples + /// The following code example demonstrates how to use to calculate an average. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet18"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static double? Average(this IEnumerable source, Func selector) { if (source == null) @@ -404,6 +513,19 @@ public static double Average(this IEnumerable source, FuncComputes the average of a sequence of values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of source. + /// A sequence of values to calculate the average of. + /// A transform function to apply to each element. + /// The average of the sequence of values. + /// or is . + /// contains no elements. + /// The sum of the elements in the sequence is larger than . + /// In Visual Basic query expression syntax, an `Aggregate Into Average()` clause translates to an invocation of . + /// The following code example demonstrates how to use to calculate an average. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet16"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet16"::: + /// Aggregate Clause (Visual Basic) public static double Average(this IEnumerable source, Func selector) { if (source == null) @@ -438,6 +560,20 @@ public static double Average(this IEnumerable source, FuncComputes the average of a sequence of nullable values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A transform function to apply to each element. + /// The average of the sequence of values, or if the source sequence is empty or contains only values that are . + /// . + /// ## Examples + /// The following code example demonstrates how to use to calculate an average. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet16"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet16"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static double? Average(this IEnumerable source, Func selector) { if (source == null) @@ -480,6 +616,22 @@ public static double Average(this IEnumerable source, FuncComputes the average of a sequence of values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A transform function to apply to each element. + /// The average of the sequence of values. + /// or is . + /// contains no elements. + /// . + /// ## Examples + /// The following code example demonstrates how to use to calculate an average. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet18"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static float Average(this IEnumerable source, Func selector) { if (source == null) @@ -511,6 +663,21 @@ public static float Average(this IEnumerable source, FuncComputes the average of a sequence of nullable values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A transform function to apply to each element. + /// The average of the sequence of values, or if the source sequence is empty or contains only values that are . + /// or is . + /// . + /// ## Examples + /// The following code example demonstrates how to use to calculate an average. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet18"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet18"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static float? Average(this IEnumerable source, Func selector) { if (source == null) @@ -553,6 +720,22 @@ public static float Average(this IEnumerable source, FuncComputes the average of a sequence of values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A transform function to apply to each element. + /// The average of the sequence of values. + /// or is . + /// contains no elements. + /// . + /// ## Examples + /// The following code example demonstrates how to use to calculate an average. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet16"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet16"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static double Average(this IEnumerable source, Func selector) { if (source == null) @@ -587,6 +770,21 @@ public static double Average(this IEnumerable source, FuncComputes the average of a sequence of nullable values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A transform function to apply to each element. + /// The average of the sequence of values, or if the source sequence is empty or contains only values that are . + /// or is . + /// . + /// ## Examples + /// The following code example demonstrates how to use to calculate an average. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet16"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet16"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static double? Average(this IEnumerable source, Func selector) { if (source == null) @@ -629,6 +827,23 @@ public static double Average(this IEnumerable source, FuncComputes the average of a sequence of values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate an average. + /// A transform function to apply to each element. + /// The average of the sequence of values. + /// or is . + /// contains no elements. + /// The sum of the elements in the sequence is larger than . + /// . + /// ## Examples + /// The following code example demonstrates how to use to calculate an average. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet16"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet16"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static decimal Average(this IEnumerable source, Func selector) { if (source == null) @@ -660,6 +875,22 @@ public static decimal Average(this IEnumerable source, FuncComputes the average of a sequence of nullable values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values to calculate the average of. + /// A transform function to apply to each element. + /// The average of the sequence of values, or if the source sequence is empty or contains only values that are . + /// or is . + /// The sum of the elements in the sequence is larger than . + /// . + /// ## Examples + /// The following code example demonstrates how to use to calculate an average. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet16"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet16"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static decimal? Average(this IEnumerable source, Func selector) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Cast.cs b/src/libraries/System.Linq/src/System/Linq/Cast.cs index 0c20609b3eb79d..8a7029e4a3b6db 100644 --- a/src/libraries/System.Linq/src/System/Linq/Cast.cs +++ b/src/libraries/System.Linq/src/System/Linq/Cast.cs @@ -8,6 +8,20 @@ namespace System.Linq { public static partial class Enumerable { + /// Filters the elements of an based on a specified type. + /// The type to filter the elements of the sequence on. + /// The whose elements to filter. + /// An that contains elements from the input sequence of type . + /// is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method returns only those elements in that can be cast to type . To instead receive an exception if an element cannot be cast to type , use . + /// This method is one of the few standard query operator methods that can be applied to a collection that has a non-parameterized type, such as an . This is because extends the type . cannot only be applied to collections that are based on the parameterized type, but collections that are based on the non-parameterized type also. + /// By applying to a collection that implements , you gain the ability to query the collection by using the standard query operators. For example, specifying a type argument of to would return an object of type `IEnumerable<Object>` in C# or `IEnumerable(Of Object)` in Visual Basic, to which the standard query operators can be applied. + /// + /// The following code example demonstrates how to use to filter the elements of an . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet69"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet69"::: public static IEnumerable OfType(this IEnumerable source) { if (source == null) @@ -29,6 +43,41 @@ private static IEnumerable OfTypeIterator(IEnumerable source) } } + /// Casts the elements of an to the specified type. + /// The type to cast the elements of to. + /// The that contains the elements to be cast to type . + /// An that contains each element of the source sequence cast to the specified type. + /// is . + /// An element in the sequence cannot be cast to type . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method enables the standard query operators to be invoked on non-generic collections by supplying the necessary type information. For example, does not implement , but by calling on the object, the standard query operators can then be used to query the sequence. + /// If an element cannot be converted to type , this method throws a . + /// The source sequence for this method is , which means the elements have the compile-time static type of `object`. The only type conversions that are performed by this method are reference conversions and unboxing conversions. The runtime type of the elements in the collection must match the target type, or in the case of value types, the runtime type of elements must be the result of a boxing conversion of the target type. Other conversion types, such as those between different numeric types, are not allowed. + /// To obtain only those elements that can be converted to type , use the method instead of . + /// In a query expression, an explicitly typed iteration variable translates to an invocation of . This example shows the syntax for an explicitly typed range variable. + /// + /// from int i in objects + /// + /// + /// From i As Integer In objects + /// + /// Use the `select` clause of a query to perform other conversion types, like the implicit numeric conversions. The following example uses both the `Cast` method and a `select` statement to convert a sequence of boxed integers to a sequence of doubles. + /// + /// IEnumerable sequence = Enumerable.Range(0, 10); + /// var doubles = from int item in sequence + /// select (double)item; + /// + /// + /// Dim sequence As IEnumerable = Enumerable.Range(0, 10) + /// Dim doubles = From item As Integer In sequence + /// Select CType(item, Double) + /// + /// + /// The following code example demonstrates how to use to enable the use of the standard query operators on an . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet19"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet19"::: + /// from clause (C# Reference) + /// From Clause (Visual Basic) public static IEnumerable< #nullable disable // there's no way to annotate the connection of the nullability of TResult to that of the source TResult diff --git a/src/libraries/System.Linq/src/System/Linq/Chunk.cs b/src/libraries/System.Linq/src/System/Linq/Chunk.cs index 661edaab5694a9..3f97507677bea6 100644 --- a/src/libraries/System.Linq/src/System/Linq/Chunk.cs +++ b/src/libraries/System.Linq/src/System/Linq/Chunk.cs @@ -7,31 +7,17 @@ namespace System.Linq { public static partial class Enumerable { - /// - /// Split the elements of a sequence into chunks of size at most . - /// + /// Split the elements of a sequence into chunks of size at most . + /// An whose elements to chunk. + /// Maximum size of each chunk. + /// The type of the elements of source. + /// An that contains the elements the input sequence split into chunks of size . + /// is null. + /// is below 1. /// - /// Every chunk except the last will be of size . - /// The last chunk will contain the remaining elements and may be of a smaller size. + /// Every chunk except the last will be of size . + /// The last chunk will contain the remaining elements and may be of a smaller size. /// - /// - /// An whose elements to chunk. - /// - /// - /// Maximum size of each chunk. - /// - /// - /// The type of the elements of source. - /// - /// - /// An that contains the elements the input sequence split into chunks of size . - /// - /// - /// is null. - /// - /// - /// is below 1. - /// public static IEnumerable Chunk(this IEnumerable source, int size) { if (source == null) @@ -71,4 +57,4 @@ private static IEnumerable ChunkIterator(IEnumerableProvides a set of ( in Visual Basic) methods for querying objects that implement . + /// The methods in this class provide an implementation of the standard query operators for querying data sources that implement . The standard query operators are general purpose methods that follow the LINQ pattern and enable you to express traversal, filter, and projection operations over data in any .NET-based programming language. + /// The majority of the methods in this class are defined as extension methods that extend . This means they can be called like an instance method on any object that implements . + /// Methods that are used in a query that returns a sequence of values do not consume the target data until the query object is enumerated. This is known as deferred execution. Methods that are used in a query that returns a singleton value execute and consume the target data immediately. + /// Standard Query Operators Overview + /// Extension Methods (C# Programming Guide) + /// Extension Methods (Visual Basic) public static partial class Enumerable { + /// Concatenates two sequences. + /// The type of the elements of the input sequences. + /// The first sequence to concatenate. + /// The sequence to concatenate to the first sequence. + /// An that contains the concatenated elements of the two input sequences. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method differs from the method because the method returns all the original elements in the input sequences. The method returns only unique elements. + /// The following code example demonstrates how to use to concatenate two sequences. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet20"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet20"::: + /// An alternative way of concatenating two sequences is to construct a collection, for example an array, of sequences and then apply the method, passing it the identity selector function. The following example demonstrates this use of . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet112"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet112"::: public static IEnumerable Concat(this IEnumerable first, IEnumerable second) { if (first == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Contains.cs b/src/libraries/System.Linq/src/System/Linq/Contains.cs index a907eea4a99281..12ee9575818229 100644 --- a/src/libraries/System.Linq/src/System/Linq/Contains.cs +++ b/src/libraries/System.Linq/src/System/Linq/Contains.cs @@ -7,10 +7,41 @@ namespace System.Linq { public static partial class Enumerable { + /// Determines whether a sequence contains a specified element by using the default equality comparer. + /// The type of the elements of . + /// A sequence in which to locate a value. + /// The value to locate in the sequence. + /// if the source sequence contains an element that has the specified value; otherwise, . + /// is . + /// + /// If the type of implements , the `Contains` method in that implementation is invoked to obtain the result. Otherwise, this method determines whether contains the specified element. + /// Enumeration is terminated as soon as a matching element is found. + /// Elements are compared to the specified value by using the default equality comparer, . + /// + /// The following code example demonstrates how to use to determine whether an array contains a specific element. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet21"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet21"::: public static bool Contains(this IEnumerable source, TSource value) => source is ICollection collection ? collection.Contains(value) : Contains(source, value, null); + /// Determines whether a sequence contains a specified element by using a specified . + /// The type of the elements of . + /// A sequence in which to locate a value. + /// The value to locate in the sequence. + /// An equality comparer to compare values. + /// if the source sequence contains an element that has the specified value; otherwise, . + /// is . + /// + /// Enumeration is terminated as soon as a matching element is found. + /// If is , the default equality comparer, , is used to compare elements to the specified value. + /// + /// The following example shows how to implement an equality comparer that can be used in the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet1"::: + /// After you implement this comparer, you can use a sequence of `Product` objects in the method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet6"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet6"::: public static bool Contains(this IEnumerable source, TSource value, IEqualityComparer? comparer) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Count.cs b/src/libraries/System.Linq/src/System/Linq/Count.cs index 14f3d457f6ea35..4e44dad0d05a4a 100644 --- a/src/libraries/System.Linq/src/System/Linq/Count.cs +++ b/src/libraries/System.Linq/src/System/Linq/Count.cs @@ -8,6 +8,21 @@ namespace System.Linq { public static partial class Enumerable { + /// Returns the number of elements in a sequence. + /// The type of the elements of . + /// A sequence that contains elements to be counted. + /// The number of elements in the input sequence. + /// is . + /// The number of elements in is larger than . + /// + /// If the type of implements , that implementation is used to obtain the count of elements. Otherwise, this method determines the count. + /// Use the method when you expect and want to allow the result to be greater than . + /// In Visual Basic query expression syntax, an `Aggregate Into Count()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to count the elements in an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet22"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet22"::: + /// Aggregate Clause (Visual Basic) public static int Count(this IEnumerable source) { if (source == null) @@ -45,6 +60,22 @@ public static int Count(this IEnumerable source) return count; } + /// Returns a number that represents how many elements in the specified sequence satisfy a condition. + /// The type of the elements of . + /// A sequence that contains elements to be tested and counted. + /// A function to test each element for a condition. + /// A number that represents how many elements in the sequence satisfy the condition in the predicate function. + /// or is . + /// The number of elements in is larger than . + /// + /// If the type of implements , that implementation is used to obtain the count of elements. Otherwise, this method determines the count. + /// You should use the method when you expect and want to allow the result to be greater than . + /// In Visual Basic query expression syntax, an `Aggregate Into Count()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to count the elements in an array that satisfy a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet23"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet23"::: + /// Aggregate Clause (Visual Basic) public static int Count(this IEnumerable source, Func predicate) { if (source == null) @@ -85,12 +116,15 @@ public static int Count(this IEnumerable source, Func. /// /// + /// /// The method performs a series of type tests, identifying common subtypes whose /// count can be determined without enumerating; this includes , /// as well as internal types used in the LINQ implementation. - /// + /// + /// /// The method is typically a constant-time operation, but ultimately this depends on the complexity /// characteristics of the underlying collection implementation. + /// /// public static bool TryGetNonEnumeratedCount(this IEnumerable source, out int count) { @@ -125,6 +159,20 @@ public static bool TryGetNonEnumeratedCount(this IEnumerable s return false; } + /// Returns an that represents the total number of elements in a sequence. + /// The type of the elements of . + /// An that contains the elements to be counted. + /// The number of elements in the source sequence. + /// is . + /// The number of elements exceeds . + /// + /// Use this method rather than when you expect the result to be greater than . + /// In Visual Basic query expression syntax, an `Aggregate Into LongCount()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to count the elements in an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet47"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet47"::: + /// Aggregate Clause (Visual Basic) public static long LongCount(this IEnumerable source) { if (source == null) @@ -147,6 +195,21 @@ public static long LongCount(this IEnumerable source) return count; } + /// Returns an that represents how many elements in a sequence satisfy a condition. + /// The type of the elements of . + /// An that contains the elements to be counted. + /// A function to test each element for a condition. + /// A number that represents how many elements in the sequence satisfy the condition in the predicate function. + /// or is . + /// The number of matching elements exceeds . + /// + /// Use this method rather than when you expect the result to be greater than . + /// In Visual Basic query expression syntax, an `Aggregate Into LongCount()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to count the elements in an array that satisfy a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet48"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet48"::: + /// Aggregate Clause (Visual Basic) public static long LongCount(this IEnumerable source, Func predicate) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/DefaultIfEmpty.cs b/src/libraries/System.Linq/src/System/Linq/DefaultIfEmpty.cs index 593a6b8a67b3d1..bf3d00d6926611 100644 --- a/src/libraries/System.Linq/src/System/Linq/DefaultIfEmpty.cs +++ b/src/libraries/System.Linq/src/System/Linq/DefaultIfEmpty.cs @@ -8,9 +8,40 @@ namespace System.Linq { public static partial class Enumerable { + /// Returns the elements of the specified sequence or the type parameter's default value in a singleton collection if the sequence is empty. + /// The type of the elements of . + /// The sequence to return a default value for if it is empty. + /// An object that contains the default value for the type if is empty; otherwise, . + /// is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The default value for reference and nullable types is . + /// This method can be used to produce a left outer join when it is combined with the ) method. + /// + /// The following code examples demonstrate how to use to provide a default value in case the source sequence is empty. + /// This example uses a non-empty sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet24"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet24"::: + /// This example uses an empty sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet25"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet25"::: + /// Joining public static IEnumerable DefaultIfEmpty(this IEnumerable source) => DefaultIfEmpty(source, default); + /// Returns the elements of the specified sequence or the specified value in a singleton collection if the sequence is empty. + /// The type of the elements of . + /// The sequence to return the specified value for if it is empty. + /// The value to return if the sequence is empty. + /// An that contains if is empty; otherwise, . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// This method can be used to produce a left outer join when it is combined with the ) method. + /// + /// The following code example demonstrates how to use the method and specify a default value. The first sequence is not empty and the second sequence is empty. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet26"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet26"::: + /// Joining public static IEnumerable DefaultIfEmpty(this IEnumerable source, TSource defaultValue) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Distinct.cs b/src/libraries/System.Linq/src/System/Linq/Distinct.cs index 008128024302bf..5db3ca0bf674bc 100644 --- a/src/libraries/System.Linq/src/System/Linq/Distinct.cs +++ b/src/libraries/System.Linq/src/System/Linq/Distinct.cs @@ -8,8 +8,46 @@ namespace System.Linq { public static partial class Enumerable { + /// Returns distinct elements from a sequence by using the default equality comparer to compare values. + /// The type of the elements of . + /// The sequence to remove duplicate elements from. + /// An that contains distinct elements from the source sequence. + /// is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method returns an unordered sequence that contains no duplicate values. It uses the default equality comparer, , to compare values. + /// In Visual Basic query expression syntax, a `Distinct` clause translates to an invocation of . + /// The default equality comparer, , is used to compare values of the types that implement the generic interface. To compare a custom data type, you need to implement this interface and provide your own and methods for the type. + /// For an example that uses to define a custom comparer, see . + /// + /// The following code example demonstrates how to use to return distinct elements from a sequence of integers. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet27"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet27"::: + /// If you want to return distinct elements from sequences of objects of some custom data type, you have to implement the generic interface in the class. The following code example shows how to implement this interface in a custom data type and provide and methods. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet1"::: + /// After you implement this interface, you can use a sequence of `Product` objects in the method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet5"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet5"::: + /// Distinct Clause (Visual Basic) public static IEnumerable Distinct(this IEnumerable source) => Distinct(source, null); + /// Returns distinct elements from a sequence by using a specified to compare values. + /// The type of the elements of . + /// The sequence to remove duplicate elements from. + /// An to compare values. + /// An that contains distinct elements from the source sequence. + /// is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method returns an unordered sequence that contains no duplicate values. If is , the default equality comparer, , is used to compare values. + /// + /// The following example shows how to implement an equality comparer that can be used in the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet1"::: + /// After you implement this comparer, you can use a sequence of `Product` objects in the method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet5"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet5"::: public static IEnumerable Distinct(this IEnumerable source, IEqualityComparer? comparer) { if (source == null) @@ -20,8 +58,31 @@ public static IEnumerable Distinct(this IEnumerable s return new DistinctIterator(source, comparer); } + /// Returns distinct elements from a sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to distinguish elements by. + /// The sequence to remove duplicate elements from. + /// A function to extract the key for each element. + /// An that contains distinct elements from the source sequence. + /// is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method returns an unordered sequence that contains no duplicate values. The default equality comparer, , is used to compare values. + /// public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) => DistinctBy(source, keySelector, null); + /// Returns distinct elements from a sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to distinguish elements by. + /// The sequence to remove duplicate elements from. + /// A function to extract the key for each element. + /// An to compare keys. + /// An that contains distinct elements from the source sequence. + /// is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method returns an unordered sequence that contains no duplicate values. If is , the default equality comparer, , is used to compare values. + /// public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector, IEqualityComparer? comparer) { if (source is null) diff --git a/src/libraries/System.Linq/src/System/Linq/ElementAt.cs b/src/libraries/System.Linq/src/System/Linq/ElementAt.cs index 46d9399d36230f..2fac28fd64997b 100644 --- a/src/libraries/System.Linq/src/System/Linq/ElementAt.cs +++ b/src/libraries/System.Linq/src/System/Linq/ElementAt.cs @@ -9,6 +9,20 @@ namespace System.Linq { public static partial class Enumerable { + /// Returns the element at a specified index in a sequence. + /// The type of the elements of . + /// An to return an element from. + /// The zero-based index of the element to retrieve. + /// The element at the specified position in the source sequence. + /// is . + /// is less than 0 or greater than or equal to the number of elements in . + /// + /// If the type of implements , that implementation is used to obtain the element at the specified index. Otherwise, this method obtains the specified element. + /// This method throws an exception if is out of range. To instead return a default value when the specified index is out of range, use the method. + /// + /// The following code example demonstrates how to use to return an element at a specific position. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet28"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet28"::: public static TSource ElementAt(this IEnumerable source, int index) { if (source == null) @@ -38,15 +52,16 @@ public static TSource ElementAt(this IEnumerable source, int i } /// Returns the element at a specified index in a sequence. + /// The type of the elements of . /// An to return an element from. /// The index of the element to retrieve, which is either from the start or the end. - /// The type of the elements of . - /// - /// is . - /// - /// is outside the bounds of the sequence. - /// + /// is . + /// is outside the bounds of the sequence. /// The element at the specified position in the sequence. + /// + /// If the type of implements , that implementation is used to obtain the element at the specified index. Otherwise, this method obtains the specified element. + /// This method throws an exception if is out of range. To instead return a default value when the specified index is out of range, use the method. + /// public static TSource ElementAt(this IEnumerable source, Index index) { if (source == null) @@ -72,6 +87,19 @@ public static TSource ElementAt(this IEnumerable source, Index return element; } + /// Returns the element at a specified index in a sequence or a default value if the index is out of range. + /// The type of the elements of . + /// An to return an element from. + /// The zero-based index of the element to retrieve. + /// () if the index is outside the bounds of the source sequence; otherwise, the element at the specified position in the source sequence. + /// is . + /// + /// If the type of implements , that implementation is used to obtain the element at the specified index. Otherwise, this method obtains the specified element. + /// The default value for reference and nullable types is . + /// + /// The following code example demonstrates how to use . This example uses an index that is outside the bounds of the array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet29"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet29"::: public static TSource? ElementAtOrDefault(this IEnumerable source, int index) { if (source == null) @@ -95,15 +123,15 @@ public static TSource ElementAt(this IEnumerable source, Index } /// Returns the element at a specified index in a sequence or a default value if the index is out of range. + /// The type of the elements of . /// An to return an element from. /// The index of the element to retrieve, which is either from the start or the end. - /// The type of the elements of . - /// - /// is . - /// - /// - /// if is outside the bounds of the sequence; otherwise, the element at the specified position in the sequence. - /// + /// is . + /// if is outside the bounds of the sequence; otherwise, the element at the specified position in the sequence. + /// + /// If the type of implements , that implementation is used to obtain the element at the specified index. Otherwise, this method obtains the specified element. + /// The default value for reference and nullable types is . + /// public static TSource? ElementAtOrDefault(this IEnumerable source, Index index) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Enumerable.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Enumerable.SpeedOpt.cs index 56c0eacec7c6fa..98db0dd3ba9f55 100644 --- a/src/libraries/System.Linq/src/System/Linq/Enumerable.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Enumerable.SpeedOpt.cs @@ -7,6 +7,21 @@ namespace System.Linq { public static partial class Enumerable { + /// + /// Returns an empty that has the specified type argument. + /// + /// The type to assign to the type parameter of the returned generic . + /// An empty whose type argument is . + /// + /// The method caches an empty sequence of type . When the object it returns is enumerated, it yields no elements. + /// In some cases, this method is useful for passing an empty sequence to a user-defined method that takes an . It can also be used to generate a neutral element for methods such as . See the Example section for an example of this use of . + /// + /// The following code example demonstrates how to use to generate an empty . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet30"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet30"::: + /// The following code example demonstrates a possible application of the method. The method is applied to a collection of string arrays. The elements of each array in the collection are added to the resulting only if that array contains four or more elements. is used to generate the seed value for because if no array in the collection has four or more elements, only the empty sequence is returned. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet31"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet31"::: public static IEnumerable Empty() => EmptyPartition.Instance; } } diff --git a/src/libraries/System.Linq/src/System/Linq/Enumerable.cs b/src/libraries/System.Linq/src/System/Linq/Enumerable.cs index 926113e3069ac0..4e644cde15ba0f 100644 --- a/src/libraries/System.Linq/src/System/Linq/Enumerable.cs +++ b/src/libraries/System.Linq/src/System/Linq/Enumerable.cs @@ -5,8 +5,28 @@ namespace System.Linq { + /// Provides a set of ( in Visual Basic) methods for querying objects that implement . + /// + /// The methods in this class provide an implementation of the standard query operators for querying data sources that implement . The standard query operators are general purpose methods that follow the LINQ pattern and enable you to express traversal, filter, and projection operations over data in any .NET-based programming language. + /// The majority of the methods in this class are defined as extension methods that extend . This means they can be called like an instance method on any object that implements . + /// Methods that are used in a query that returns a sequence of values do not consume the target data until the query object is enumerated. This is known as deferred execution. Methods that are used in a query that returns a singleton value execute and consume the target data immediately. + /// + /// Standard Query Operators Overview + /// Extension Methods (C# Programming Guide) + /// Extension Methods (Visual Basic) public static partial class Enumerable { + /// Returns the input typed as . + /// The type of the elements of . + /// The sequence to type as . + /// The input sequence typed as . + /// + /// The method has no effect other than to change the compile-time type of from a type that implements to itself. + /// can be used to choose between query implementations when a sequence implements but also has a different set of public query methods available. For example, given a generic class `Table` that implements and has its own methods such as `Where`, `Select`, and `SelectMany`, a call to `Where` would invoke the public `Where` method of `Table`. A `Table` type that represents a database table could have a `Where` method that takes the predicate argument as an expression tree and converts the tree to SQL for remote execution. If remote execution is not desired, for example because the predicate invokes a local method, the method can be used to hide the custom methods and instead make the standard query operators available. + /// + /// The following code example demonstrates how to use to hide a type's custom `Where` method when the standard query operator implementation is desired. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet108"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet108"::: public static IEnumerable AsEnumerable(this IEnumerable source) => source; } } diff --git a/src/libraries/System.Linq/src/System/Linq/Except.cs b/src/libraries/System.Linq/src/System/Linq/Except.cs index f590cfd5488d0b..41ee12911aa70a 100644 --- a/src/libraries/System.Linq/src/System/Linq/Except.cs +++ b/src/libraries/System.Linq/src/System/Linq/Except.cs @@ -7,6 +7,26 @@ namespace System.Linq { public static partial class Enumerable { + /// Produces the set difference of two sequences by using the default equality comparer to compare values. + /// The type of the elements of the input sequences. + /// An whose elements that are not also in will be returned. + /// An whose elements that also occur in the first sequence will cause those elements to be removed from the returned sequence. + /// A sequence that contains the set difference of the elements of two sequences. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The default equality comparer, , is used to compare values of the types. + /// To compare a custom data type, you need to override the and the methods, and optionally implement the generic interface in the custom type. For more information, see the property. + /// + /// The following code example demonstrates how to use the method to compare two sequences of numbers and return elements that appear only in the first sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet34"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet34"::: + /// If you want to compare sequences of objects of some custom data type, you have to implement the generic interface in a helper class. The following code example shows how to implement this interface in a custom data type and override and methods. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet9"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet9"::: + /// After you implement this interface, you can use sequences of `ProductA` objects in the method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet7"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet7"::: public static IEnumerable Except(this IEnumerable first, IEnumerable second) { if (first == null) @@ -22,6 +42,21 @@ public static IEnumerable Except(this IEnumerable fir return ExceptIterator(first, second, null); } + /// Produces the set difference of two sequences by using the specified to compare values. + /// The type of the elements of the input sequences. + /// An whose elements that are not also in will be returned. + /// An whose elements that also occur in the first sequence will cause those elements to be removed from the returned sequence. + /// An to compare values. + /// A sequence that contains the set difference of the elements of two sequences. + /// or is . + /// If is , the default equality comparer, , is used to compare values. + /// If you want to compare sequences of objects of some custom data type, you have to implement the generic interface in a helper class. The following code example shows how to implement this interface in a custom data type and provide and methods. + /// The following example shows how to implement an equality comparer that can be used in the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet1"::: + /// After you implement this comparer, you can use sequences of `Product` objects in the method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet7"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet7"::: public static IEnumerable Except(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) { if (first == null) diff --git a/src/libraries/System.Linq/src/System/Linq/First.cs b/src/libraries/System.Linq/src/System/Linq/First.cs index 7f59d1c63b5872..322f130dc18149 100644 --- a/src/libraries/System.Linq/src/System/Linq/First.cs +++ b/src/libraries/System.Linq/src/System/Linq/First.cs @@ -8,6 +8,16 @@ namespace System.Linq { public static partial class Enumerable { + /// Returns the first element of a sequence. + /// The type of the elements of . + /// The to return the first element of. + /// The first element in the specified sequence. + /// is . + /// The source sequence is empty. + /// The method throws an exception if contains no elements. To instead return a default value when the source sequence is empty, use the method. + /// The following code example demonstrates how to use to return the first element of an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet35"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet35"::: public static TSource First(this IEnumerable source) { TSource? first = source.TryGetFirst(out bool found); @@ -19,6 +29,19 @@ public static TSource First(this IEnumerable source) return first!; } + /// Returns the first element in a sequence that satisfies a specified condition. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// The first element in the sequence that passes the test in the specified predicate function. + /// or is . + /// No element satisfies the condition in . + /// -or- + /// The source sequence is empty. + /// The method throws an exception if no matching element is found in . To instead return a default value when no matching element is found, use the method. + /// The following code example demonstrates how to use to return the first element of an array that satisfies a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet36"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet36"::: public static TSource First(this IEnumerable source, Func predicate) { TSource? first = source.TryGetFirst(predicate, out bool found); @@ -30,18 +53,56 @@ public static TSource First(this IEnumerable source, FuncReturns the first element of a sequence, or a default value if the sequence contains no elements. + /// The type of the elements of . + /// The to return the first element of. + /// () if is empty; otherwise, the first element in . + /// is . + /// + /// The default value for reference and nullable types is . + /// The method does not provide a way to specify a default value. If you want to specify a default value other than `default(TSource)`, use the method as described in the Example section. + /// + /// The following code example demonstrates how to use on an empty array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet37"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet37"::: + /// Sometimes the value of `default(TSource)` is not the default value that you want to use if the collection contains no elements. Instead of checking the result for the unwanted default value and then changing it if necessary, you can use the method to specify the default value that you want to use if the collection is empty. Then, call to obtain the first element. The following code example uses both techniques to obtain a default value of 1 if a collection of numeric months is empty. Because the default value for an integer is 0, which does not correspond to any month, the default value must be specified as 1 instead. The first result variable is checked for the unwanted default value after the query has finished executing. The second result variable is obtained by using to specify a default value of 1. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet126"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet126"::: public static TSource? FirstOrDefault(this IEnumerable source) => source.TryGetFirst(out _); + /// Returns the first element of a sequence, or a default value if the sequence contains no elements. + /// The type of the elements of . + /// The to return the first element of. + /// The default value to return if the sequence is empty. + /// if is empty; otherwise, the first element in . + /// is . public static TSource FirstOrDefault(this IEnumerable source, TSource defaultValue) { TSource? first = source.TryGetFirst(out bool found); return found ? first! : defaultValue; } + /// Returns the first element of the sequence that satisfies a condition or a default value if no such element is found. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// () if is empty or if no element passes the test specified by ; otherwise, the first element in that passes the test specified by . + /// or is . + /// The default value for reference and nullable types is . + /// The following code example demonstrates how to use by passing in a predicate. In the second call to the method, there is no element in the array that satisfies the condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet38"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet38"::: public static TSource? FirstOrDefault(this IEnumerable source, Func predicate) => source.TryGetFirst(predicate, out _); + /// Returns the first element of the sequence that satisfies a condition or a default value if no such element is found. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// The default value to return if the sequence is empty. + /// if is empty or if no element passes the test specified by ; otherwise, the first element in that passes the test specified by . + /// or is . public static TSource FirstOrDefault(this IEnumerable source, Func predicate, TSource defaultValue) { TSource? first = source.TryGetFirst(predicate, out bool found); diff --git a/src/libraries/System.Linq/src/System/Linq/GroupJoin.cs b/src/libraries/System.Linq/src/System/Linq/GroupJoin.cs index 71175805b97fc6..bd578fea5a7c2a 100644 --- a/src/libraries/System.Linq/src/System/Linq/GroupJoin.cs +++ b/src/libraries/System.Linq/src/System/Linq/GroupJoin.cs @@ -7,6 +7,35 @@ namespace System.Linq { public static partial class Enumerable { + /// Correlates the elements of two sequences based on equality of keys and groups the results. The default equality comparer is used to compare keys. + /// The type of the elements of the first sequence. + /// The type of the elements of the second sequence. + /// The type of the keys returned by the key selector functions. + /// The type of the result elements. + /// The first sequence to join. + /// The sequence to join to the first sequence. + /// A function to extract the join key from each element of the first sequence. + /// A function to extract the join key from each element of the second sequence. + /// A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence. + /// An that contains elements of type that are obtained by performing a grouped join on two sequences. + /// or or or or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The default equality comparer, , is used to hash and compare keys. + /// produces hierarchical results, which means that elements from are paired with collections of matching elements from . `GroupJoin` enables you to base your results on a whole set of matches for each element of . + /// [!NOTE] + /// > If there are no correlated elements in `inner` for a given element of `outer`, the sequence of matches for that element will be empty but will still appear in the results. + /// ]]> + /// The function is called only one time for each element together with a collection of all the elements that match the element. This differs from the method, in which the result selector function is invoked on pairs that contain one element from and one element from . + /// `GroupJoin` preserves the order of the elements of , and for each element of , the order of the matching elements from . + /// has no direct equivalent in traditional relational database terms. However, this method does implement a superset of inner joins and left outer joins. Both of these operations can be written in terms of a grouped join. See Join Operations. + /// In query expression syntax, a `join … into` (Visual C#) or `Group Join` (Visual Basic) clause translates to an invocation of . + /// The following code example demonstrates how to use to perform a grouped join on two sequences. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet40"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet40"::: + /// Join Operations + /// join clause (C# Reference) + /// Group Join Clause (Visual Basic) public static IEnumerable GroupJoin(this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func, TResult> resultSelector) { if (outer == null) @@ -37,6 +66,30 @@ public static IEnumerable GroupJoin(this return GroupJoinIterator(outer, inner, outerKeySelector, innerKeySelector, resultSelector, null); } + /// Correlates the elements of two sequences based on key equality and groups the results. A specified is used to compare keys. + /// The type of the elements of the first sequence. + /// The type of the elements of the second sequence. + /// The type of the keys returned by the key selector functions. + /// The type of the result elements. + /// The first sequence to join. + /// The sequence to join to the first sequence. + /// A function to extract the join key from each element of the first sequence. + /// A function to extract the join key from each element of the second sequence. + /// A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence. + /// An to hash and compare keys. + /// An that contains elements of type that are obtained by performing a grouped join on two sequences. + /// or or or or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// If is , the default equality comparer, , is used to hash and compare keys. + /// produces hierarchical results, which means that elements from are paired with collections of matching elements from . `GroupJoin` enables you to base your results on a whole set of matches for each element of . + /// [!NOTE] + /// > If there are no correlated elements in `inner` for a given element of `outer`, the sequence of matches for that element will be empty but will still appear in the results. + /// ]]> + /// The function is called only one time for each element together with a collection of all the elements that match the element. This differs from the method in which the result selector function is invoked on pairs that contain one element from and one element from . + /// `GroupJoin` preserves the order of the elements of , and for each element of , the order of the matching elements from . + /// has no direct equivalent in traditional relational database terms. However, this method does implement a superset of inner joins and left outer joins. Both of these operations can be written in terms of a grouped join. See Join Operations. + /// Performing Join Operations public static IEnumerable GroupJoin(this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func, TResult> resultSelector, IEqualityComparer? comparer) { if (outer == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Grouping.cs b/src/libraries/System.Linq/src/System/Linq/Grouping.cs index b12629ffc8e2f2..74a73552388686 100644 --- a/src/libraries/System.Linq/src/System/Linq/Grouping.cs +++ b/src/libraries/System.Linq/src/System/Linq/Grouping.cs @@ -7,35 +7,218 @@ namespace System.Linq { + /// Provides a set of ( in Visual Basic) methods for querying objects that implement . + /// + /// The methods in this class provide an implementation of the standard query operators for querying data sources that implement . The standard query operators are general purpose methods that follow the LINQ pattern and enable you to express traversal, filter, and projection operations over data in any .NET-based programming language. + /// The majority of the methods in this class are defined as extension methods that extend . This means they can be called like an instance method on any object that implements . + /// Methods that are used in a query that returns a sequence of values do not consume the target data until the query object is enumerated. This is known as deferred execution. Methods that are used in a query that returns a singleton value execute and consume the target data immediately. + /// + /// Standard Query Operators Overview + /// Extension Methods (C# Programming Guide) + /// Extension Methods (Visual Basic) public static partial class Enumerable { + /// Groups the elements of a sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of the key returned by . + /// An whose elements to group. + /// A function to extract the key for each element. + /// An IEnumerable<IGrouping<TKey, TSource>> in C# or IEnumerable(Of IGrouping(Of TKey, TSource)) in Visual Basic where each object contains a sequence of objects and a key. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// [!NOTE] + /// > For examples of `GroupBy`, see the following articles: + /// > + /// > - + /// > - + /// > - + /// ]]> + /// The method returns a collection of objects, one for each distinct key that was encountered. An is an that also has a key associated with its elements. + /// The objects are yielded in an order based on the order of the elements in that produced the first key of each . Elements in a grouping are yielded in the order they appear in . + /// The default equality comparer is used to compare keys. + /// In query expression syntax, a `group by` (Visual C#) or `Group By Into` (Visual Basic) clause translates to an invocation of . For more information and usage examples, see [group clause](/dotnet/csharp/language-reference/keywords/group-clause) and [Group By Clause](/dotnet/visual-basic/language-reference/queries/group-by-clause). + /// group clause (C# Reference) + /// Group By Clause (Visual Basic) public static IEnumerable> GroupBy(this IEnumerable source, Func keySelector) => new GroupedEnumerable(source, keySelector, null); + /// Groups the elements of a sequence according to a specified key selector function and compares the keys by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by . + /// An whose elements to group. + /// A function to extract the key for each element. + /// An to compare keys. + /// An IEnumerable<IGrouping<TKey, TSource>> in C# or IEnumerable(Of IGrouping(Of TKey, TSource)) in Visual Basic where each object contains a collection of objects and a key. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// [!NOTE] + /// > For examples of `GroupBy`, see the following articles: + /// > + /// > - + /// > - + /// > - + /// ]]> + /// The method returns a collection of objects, one for each distinct key that was encountered. An is an that also has a key associated with its elements. + /// The objects are yielded in an order based on the order of the elements in that produced the first key of each . Elements in a grouping are yielded in the order they appear in . + /// If is , the default equality comparer is used to compare keys. + /// If two keys are considered equal according to , the first key is chosen as the key for that grouping. + /// In query expression syntax, a `group by` (Visual C#) or `Group By Into` (Visual Basic) clause translates to an invocation of . For more information and usage examples, see [group clause](/dotnet/csharp/language-reference/keywords/group-clause) and [Group By Clause](/dotnet/visual-basic/language-reference/queries/group-by-clause). + /// group clause (C# Reference) + /// Group By Clause (Visual Basic) public static IEnumerable> GroupBy(this IEnumerable source, Func keySelector, IEqualityComparer? comparer) => new GroupedEnumerable(source, keySelector, comparer); + /// Groups the elements of a sequence according to a specified key selector function and projects the elements for each group by using a specified function. + /// The type of the elements of . + /// The type of the key returned by . + /// The type of the elements in the . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to map each source element to an element in the . + /// An IEnumerable<IGrouping<TKey, TElement>> in C# or IEnumerable(Of IGrouping(Of TKey, TElement)) in Visual Basic where each object contains a collection of objects of type and a key. + /// or or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method returns a collection of objects, one for each distinct key that was encountered. An is an that also has a key associated with its elements. + /// The objects are yielded in an order based on the order of the elements in that produced the first key of each . Elements in a grouping are yielded in the order that the elements that produced them appear in . + /// The default equality comparer is used to compare keys. + /// + /// The following code example demonstrates how to use to group the elements of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet39"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet39"::: + /// In query expression syntax, a `group by` (Visual C#) or `Group By Into` (Visual Basic) clause translates to an invocation of . The translation of the query expression in the following example is equivalent to the query in the example above. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet122"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet122"::: + /// [!NOTE] + /// > In a Visual C# or Visual Basic query expression, the element and key selection expressions occur in the reverse order from their argument positions in a call to the method. + /// ]]> + /// + /// group clause (C# Reference) + /// Group By Clause (Visual Basic) public static IEnumerable> GroupBy(this IEnumerable source, Func keySelector, Func elementSelector) => new GroupedEnumerable(source, keySelector, elementSelector, null); + /// Groups the elements of a sequence according to a key selector function. The keys are compared by using a comparer and each group's elements are projected by using a specified function. + /// The type of the elements of . + /// The type of the key returned by . + /// The type of the elements in the . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to map each source element to an element in an . + /// An to compare keys. + /// An IEnumerable<IGrouping<TKey, TElement>> in C# or IEnumerable(Of IGrouping(Of TKey, TElement)) in Visual Basic where each object contains a collection of objects of type and a key. + /// or or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// [!NOTE] + /// > For examples of `GroupBy`, see the following articles: + /// > + /// > - + /// > - + /// > - + /// ]]> + /// The method returns a collection of objects, one for each distinct key that was encountered. An is an that also has a key associated with its elements. + /// The objects are yielded in an order based on the order of the elements in that produced the first key of each . Elements in a grouping are yielded in the order that the elements that produced them appear in . + /// If is , the default equality comparer is used to compare keys. + /// If two keys are considered equal according to , the first key is chosen as the key for that grouping. + /// In query expression syntax, a `group by` (Visual C#) or `Group By Into` (Visual Basic) clause translates to an invocation of . For more information and usage examples, see [group clause](/dotnet/csharp/language-reference/keywords/group-clause) and [Group By Clause](/dotnet/visual-basic/language-reference/queries/group-by-clause). + /// group clause (C# Reference) + /// Group By Clause (Visual Basic) public static IEnumerable> GroupBy(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer? comparer) => new GroupedEnumerable(source, keySelector, elementSelector, comparer); + /// Groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. + /// The type of the elements of . + /// The type of the key returned by . + /// The type of the result value returned by . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to create a result value from each group. + /// A collection of elements of type where each element represents a projection over a group and its key. + /// In query expression syntax, a `group by` (Visual C#) or `Group By Into` (Visual Basic) clause translates to an invocation of . + /// The following code example demonstrates how to use to group the elements of a sequence and project a sequence of results of type . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet15"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet15"::: + /// group clause (C# Reference) + /// Group By Clause (Visual Basic) public static IEnumerable GroupBy(this IEnumerable source, Func keySelector, Func, TResult> resultSelector) => new GroupedResultEnumerable(source, keySelector, resultSelector, null); + /// Groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. The elements of each group are projected by using a specified function. + /// The type of the elements of . + /// The type of the key returned by . + /// The type of the elements in each . + /// The type of the result value returned by . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to map each source element to an element in an . + /// A function to create a result value from each group. + /// A collection of elements of type where each element represents a projection over a group and its key. + /// In query expression syntax, a `group by` (Visual C#) or `Group By Into` (Visual Basic) clause translates to an invocation of . + /// The following code example demonstrates how to use to group the projected elements of a sequence and then project a sequence of results of type . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet125"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet125"::: + /// group clause (C# Reference) + /// Group By Clause (Visual Basic) public static IEnumerable GroupBy(this IEnumerable source, Func keySelector, Func elementSelector, Func, TResult> resultSelector) => new GroupedResultEnumerable(source, keySelector, elementSelector, resultSelector, null); + /// Groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. The keys are compared by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by . + /// The type of the result value returned by . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to create a result value from each group. + /// An to compare keys with. + /// A collection of elements of type where each element represents a projection over a group and its key. + /// group clause (C# Reference) + /// Group By Clause (Visual Basic) public static IEnumerable GroupBy(this IEnumerable source, Func keySelector, Func, TResult> resultSelector, IEqualityComparer? comparer) => new GroupedResultEnumerable(source, keySelector, resultSelector, comparer); + /// Groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. Key values are compared by using a specified comparer, and the elements of each group are projected by using a specified function. + /// The type of the elements of . + /// The type of the key returned by . + /// The type of the elements in each . + /// The type of the result value returned by . + /// An whose elements to group. + /// A function to extract the key for each element. + /// A function to map each source element to an element in an . + /// A function to create a result value from each group. + /// An to compare keys with. + /// A collection of elements of type where each element represents a projection over a group and its key. + /// group clause (C# Reference) + /// Group By Clause (Visual Basic) public static IEnumerable GroupBy(this IEnumerable source, Func keySelector, Func elementSelector, Func, TResult> resultSelector, IEqualityComparer? comparer) => new GroupedResultEnumerable(source, keySelector, elementSelector, resultSelector, comparer); } + /// Represents a collection of objects that have a common key. + /// The type of the key of the . + /// The type of the values in the . + /// + /// An is an that additionally has a key. The key represents the attribute that is common to each value in the . + /// The values of an are accessed much as the elements of an are accessed. For example, you can access the values by using a `foreach` in Visual C# or `For Each` in Visual Basic loop to iterate through the object. The Example section contains a code example that shows you how to access both the key and the values of an object. + /// The type is used by the standard query operator methods, which return a sequence of elements of type . + /// + /// The following example demonstrates how to work with an object. + /// In this example, is called on the array of objects returned by . groups the objects based on the value of their property. Each unique value for in the array of objects becomes a key for a new object, and the objects that have that key form the object's sequence of values. + /// Finally, the method is called on the sequence of objects to obtain just the first object. + /// The example then outputs the key of the object and the property of each value in the object's sequence of values. Notice that to access an object's sequence of values, you simply use the variable itself. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.IGrouping/CS/igrouping.cs" interactive="try-dotnet-method" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.IGrouping/VB/IGrouping.vb" id="Snippet1"::: public interface IGrouping : IEnumerable { + /// Gets the key of the . + /// The key of the . + /// The key of an represents the attribute that is common to each value in the . + /// The following example demonstrates how to use the property to label each object in a sequence of objects. The method is used to obtain a sequence of objects. The `foreach` in Visual C# or `For Each` in Visual Basic loop then iterates through each object, outputting its key and the number of values it contains. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.IGrouping/CS/igrouping.cs" interactive="try-dotnet-method" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.IGrouping/VB/IGrouping.vb" id="Snippet2"::: TKey Key { get; } } diff --git a/src/libraries/System.Linq/src/System/Linq/Intersect.cs b/src/libraries/System.Linq/src/System/Linq/Intersect.cs index a9519a6e73a7b0..2de27d322873db 100644 --- a/src/libraries/System.Linq/src/System/Linq/Intersect.cs +++ b/src/libraries/System.Linq/src/System/Linq/Intersect.cs @@ -7,8 +7,53 @@ namespace System.Linq { public static partial class Enumerable { + /// Produces the set intersection of two sequences by using the default equality comparer to compare values. + /// The type of the elements of the input sequences. + /// An whose distinct elements that also appear in will be returned. + /// An whose distinct elements that also appear in the first sequence will be returned. + /// A sequence that contains the elements that form the set intersection of two sequences. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The intersection of two sets A and B is defined as the set that contains all the elements of A that also appear in B, but no other elements. + /// When the object returned by this method is enumerated, `Intersect` yields distinct elements occurring in both sequences in the order in which they appear in . + /// The default equality comparer, , is used to compare values of the types. + /// To compare a custom data type, you need to override the and the methods, and optionally implement the generic interface in the custom type. For more information, see the property. + /// + /// The following code example demonstrates how to use to return the elements that appear in each of two sequences of integers. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet41"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet41"::: + /// If you want to compare sequences of objects of some custom data type, you have to implement the generic interface in a helper class. The following code example shows how to implement this interface in a custom data type and override and methods. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet9"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet9"::: + /// After you implement this interface, you can use sequences of `ProductA` objects in the `Intersect` method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet10"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet10"::: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet3"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet3"::: public static IEnumerable Intersect(this IEnumerable first, IEnumerable second) => Intersect(first, second, null); + /// Produces the set intersection of two sequences by using the specified to compare values. + /// The type of the elements of the input sequences. + /// An whose distinct elements that also appear in will be returned. + /// An whose distinct elements that also appear in the first sequence will be returned. + /// An to compare values. + /// A sequence that contains the elements that form the set intersection of two sequences. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The intersection of two sets A and B is defined as the set that contains all the elements of A that also appear in B, but no other elements. + /// When the object returned by this method is enumerated, `Intersect` yields distinct elements occurring in both sequences in the order in which they appear in . + /// If is , the default equality comparer, , is used to compare values. + /// + /// The following example shows how to implement an equality comparer that can be used in the `Intersect` method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet1"::: + /// After you implement this comparer, you can use sequences of `Product` objects in the `Intersect` method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet2"::: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet3"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet3"::: public static IEnumerable Intersect(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) { if (first == null) @@ -24,8 +69,37 @@ public static IEnumerable Intersect(this IEnumerable return IntersectIterator(first, second, comparer); } + /// Produces the set intersection of two sequences according to a specified key selector function. + /// The type of the elements of the input sequences. + /// The type of key to identify elements by. + /// An whose distinct elements that also appear in will be returned. + /// An whose distinct elements that also appear in the first sequence will be returned. + /// A function to extract the key for each element. + /// A sequence that contains the elements that form the set intersection of two sequences. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The intersection of two sets A and B is defined as the set that contains all the elements of A that also appear in B, but no other elements. + /// When the object returned by this method is enumerated, `Intersect` yields distinct elements occurring in both sequences in the order in which they appear in . + /// The default equality comparer, , is used to compare values. + /// public static IEnumerable IntersectBy(this IEnumerable first, IEnumerable second, Func keySelector) => IntersectBy(first, second, keySelector, null); + /// Produces the set intersection of two sequences according to a specified key selector function. + /// The type of the elements of the input sequences. + /// The type of key to identify elements by. + /// An whose distinct elements that also appear in will be returned. + /// An whose distinct elements that also appear in the first sequence will be returned. + /// A function to extract the key for each element. + /// An to compare keys. + /// A sequence that contains the elements that form the set intersection of two sequences. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The intersection of two sets A and B is defined as the set that contains all the elements of A that also appear in B, but no other elements. + /// When the object returned by this method is enumerated, `Intersect` yields distinct elements occurring in both sequences in the order in which they appear in . + /// If is , the default equality comparer, , is used to compare values. + /// public static IEnumerable IntersectBy(this IEnumerable first, IEnumerable second, Func keySelector, IEqualityComparer? comparer) { if (first is null) diff --git a/src/libraries/System.Linq/src/System/Linq/Iterator.cs b/src/libraries/System.Linq/src/System/Linq/Iterator.cs index b9e8c7b58c0548..a0b94f83480549 100644 --- a/src/libraries/System.Linq/src/System/Linq/Iterator.cs +++ b/src/libraries/System.Linq/src/System/Linq/Iterator.cs @@ -6,6 +6,13 @@ namespace System.Linq { + /// Provides a set of ( in Visual Basic) methods for querying objects that implement . + /// The methods in this class provide an implementation of the standard query operators for querying data sources that implement . The standard query operators are general purpose methods that follow the LINQ pattern and enable you to express traversal, filter, and projection operations over data in any .NET-based programming language. + /// The majority of the methods in this class are defined as extension methods that extend . This means they can be called like an instance method on any object that implements . + /// Methods that are used in a query that returns a sequence of values do not consume the target data until the query object is enumerated. This is known as deferred execution. Methods that are used in a query that returns a singleton value execute and consume the target data immediately. + /// Standard Query Operators Overview + /// Extension Methods (C# Programming Guide) + /// Extension Methods (Visual Basic) public static partial class Enumerable { /// diff --git a/src/libraries/System.Linq/src/System/Linq/Join.cs b/src/libraries/System.Linq/src/System/Linq/Join.cs index 82618ed237503b..e266f53968c4f5 100644 --- a/src/libraries/System.Linq/src/System/Linq/Join.cs +++ b/src/libraries/System.Linq/src/System/Linq/Join.cs @@ -7,6 +7,32 @@ namespace System.Linq { public static partial class Enumerable { + /// Correlates the elements of two sequences based on matching keys. The default equality comparer is used to compare keys. + /// The type of the elements of the first sequence. + /// The type of the elements of the second sequence. + /// The type of the keys returned by the key selector functions. + /// The type of the result elements. + /// The first sequence to join. + /// The sequence to join to the first sequence. + /// A function to extract the join key from each element of the first sequence. + /// A function to extract the join key from each element of the second sequence. + /// A function to create a result element from two matching elements. + /// An that has elements of type that are obtained by performing an inner join on two sequences. + /// or or or or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The default equality comparer, , is used to hash and compare keys. + /// A join refers to the operation of correlating the elements of two sources of information based on a common key. brings the two information sources and the keys by which they are matched together in one method call. This differs from the use of `SelectMany`, which requires more than one method call to perform the same operation. + /// preserves the order of the elements of , and for each of these elements, the order of the matching elements of . + /// In query expression syntax, a `join` (Visual C#) or `Join` (Visual Basic) clause translates to an invocation of . + /// In relational database terms, the method implements an inner equijoin. 'Inner' means that only elements that have a match in the other sequence are included in the results. An 'equijoin' is a join in which the keys are compared for equality. A left outer join operation has no dedicated standard query operator, but can be performed by using the method. See Join Operations. + /// + /// The following code example demonstrates how to use to perform an inner join of two sequences based on a common key. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet42"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet42"::: + /// Joining + /// join clause (C# Reference) + /// Join Clause (Visual Basic) public static IEnumerable Join(this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector) { if (outer == null) @@ -37,6 +63,27 @@ public static IEnumerable Join(this IEnu return JoinIterator(outer, inner, outerKeySelector, innerKeySelector, resultSelector, null); } + /// Correlates the elements of two sequences based on matching keys. A specified is used to compare keys. + /// The type of the elements of the first sequence. + /// The type of the elements of the second sequence. + /// The type of the keys returned by the key selector functions. + /// The type of the result elements. + /// The first sequence to join. + /// The sequence to join to the first sequence. + /// A function to extract the join key from each element of the first sequence. + /// A function to extract the join key from each element of the second sequence. + /// A function to create a result element from two matching elements. + /// An to hash and compare keys. + /// An that has elements of type that are obtained by performing an inner join on two sequences. + /// or or or or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// If is , the default equality comparer, , is used to hash and compare keys. + /// A join refers to the operation of correlating the elements of two sources of information based on a common key. brings the two information sources and the keys by which they are matched together in one method call. This differs from the use of `SelectMany`, which requires more than one method call to perform the same operation. + /// preserves the order of the elements of , and for each of these elements, the order of the matching elements of . + /// In relational database terms, the method implements an inner equijoin. 'Inner' means that only elements that have a match in the other sequence are included in the results. An 'equijoin' is a join in which the keys are compared for equality. A left outer join operation has no dedicated standard query operator, but can be performed by using the method. See Join Operations. + /// + /// Joining public static IEnumerable Join(this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector, IEqualityComparer? comparer) { if (outer == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Last.cs b/src/libraries/System.Linq/src/System/Linq/Last.cs index 16318de2574ccc..14c9b134135f46 100644 --- a/src/libraries/System.Linq/src/System/Linq/Last.cs +++ b/src/libraries/System.Linq/src/System/Linq/Last.cs @@ -6,8 +6,27 @@ namespace System.Linq { + /// Provides a set of ( in Visual Basic) methods for querying objects that implement . + /// + /// The methods in this class provide an implementation of the standard query operators for querying data sources that implement . The standard query operators are general purpose methods that follow the LINQ pattern and enable you to express traversal, filter, and projection operations over data in any .NET-based programming language. + /// The majority of the methods in this class are defined as extension methods that extend . This means they can be called like an instance method on any object that implements . + /// Methods that are used in a query that returns a sequence of values do not consume the target data until the query object is enumerated. This is known as deferred execution. Methods that are used in a query that returns a singleton value execute and consume the target data immediately. + /// + /// Standard Query Operators Overview + /// Extension Methods (C# Programming Guide) + /// Extension Methods (Visual Basic) public static partial class Enumerable { + /// Returns the last element of a sequence. + /// The type of the elements of . + /// An to return the last element of. + /// The value at the last position in the source sequence. + /// is . + /// The source sequence is empty. + /// The method throws an exception if contains no elements. To instead return a default value when the source sequence is empty, use the method. + /// The following code example demonstrates how to use to return the last element of an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet43"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet43"::: public static TSource Last(this IEnumerable source) { TSource? last = source.TryGetLast(out bool found); @@ -19,6 +38,19 @@ public static TSource Last(this IEnumerable source) return last!; } + /// Returns the last element of a sequence that satisfies a specified condition. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// The last element in the sequence that passes the test in the specified predicate function. + /// or is . + /// No element satisfies the condition in . + /// -or- + /// The source sequence is empty. + /// The method throws an exception if no matching element is found in . To instead return a default value when no matching element is found, use the method. + /// The following code example demonstrates how to use to return the last element of an array that satisfies a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet44"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet44"::: public static TSource Last(this IEnumerable source, Func predicate) { TSource? last = source.TryGetLast(predicate, out bool found); @@ -30,19 +62,56 @@ public static TSource Last(this IEnumerable source, FuncReturns the last element of a sequence, or a default value if the sequence contains no elements. + /// The type of the elements of . + /// An to return the last element of. + /// () if the source sequence is empty; otherwise, the last element in the . + /// is . + /// + /// The default value for reference and nullable types is . + /// The method does not provide a way to specify a default value. If you want to specify a default value other than `default(TSource)`, use the method as described in the Example section. + /// + /// The following code example demonstrates how to use on an empty array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet45"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet45"::: + /// Sometimes the value of `default(TSource)` is not the default value that you want to use if the collection contains no elements. Instead of checking the result for the unwanted default value and then changing it if necessary, you can use the method to specify the default value that you want to use if the collection is empty. Then, call to obtain the last element. The following code example uses both techniques to obtain a default value of 1 if a collection of numeric days of the month is empty. Because the default value for an integer is 0, which does not correspond to any day of the month, the default value must be specified as 1 instead. The first result variable is checked for the unwanted default value after the query has finished executing. The second result variable is obtained by using to specify a default value of 1. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet127"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet127"::: public static TSource? LastOrDefault(this IEnumerable source) => source.TryGetLast(out _); - + /// Returns the last element of a sequence, or a default value if the sequence contains no elements. + /// The type of the elements of . + /// An to return the last element of. + /// The default value to return if the sequence is empty. + /// if the source sequence is empty; otherwise, the last element in the . + /// is . public static TSource LastOrDefault(this IEnumerable source, TSource defaultValue) { TSource? last = source.TryGetLast(out bool found); return found ? last! : defaultValue; } + /// Returns the last element of a sequence that satisfies a condition or a default value if no such element is found. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// () if the sequence is empty or if no elements pass the test in the predicate function; otherwise, the last element that passes the test in the predicate function. + /// or is . + /// The default value for reference and nullable types is . + /// The following code example demonstrates how to use by passing in a predicate. In the second call to the method, there is no element in the sequence that satisfies the condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet46"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet46"::: public static TSource? LastOrDefault(this IEnumerable source, Func predicate) => source.TryGetLast(predicate, out _); + /// Returns the last element of a sequence that satisfies a condition or a default value if no such element is found. + /// The type of the elements of . + /// An to return an element from. + /// A function to test each element for a condition. + /// The default value to return if the sequence is empty. + /// if the sequence is empty or if no elements pass the test in the predicate function; otherwise, the last element that passes the test in the predicate function. + /// or is . public static TSource LastOrDefault(this IEnumerable source, Func predicate, TSource defaultValue) { var last = source.TryGetLast(predicate, out bool found); diff --git a/src/libraries/System.Linq/src/System/Linq/Lookup.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Lookup.SpeedOpt.cs index 5fc89fc52555b6..b98d8dd794e9cd 100644 --- a/src/libraries/System.Linq/src/System/Linq/Lookup.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Lookup.SpeedOpt.cs @@ -6,6 +6,16 @@ namespace System.Linq { + /// Represents a collection of keys each mapped to one or more values. + /// A resembles a . The difference is that a maps keys to single values, whereas a maps keys to collections of values. + /// You can create an instance of a by calling on an object that implements . + /// [!NOTE] + /// > There is no public constructor to create a new instance of a . Additionally, objects are immutable, that is, you cannot add or remove elements or keys from a object after it has been created. + /// ]]> + /// The following example creates a from a collection of objects. It then enumerates the and outputs each key and each value in the key's associated collection of values. It also demonstrates how to use the properties and and the methods and . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Lookup/CS/lookup.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Lookup/VB/Lookup.vb" id="Snippet1"::: public partial class Lookup : IIListProvider> { IGrouping[] IIListProvider>.ToArray() diff --git a/src/libraries/System.Linq/src/System/Linq/Lookup.cs b/src/libraries/System.Linq/src/System/Linq/Lookup.cs index 65ee9906894ac1..952c45799895da 100644 --- a/src/libraries/System.Linq/src/System/Linq/Lookup.cs +++ b/src/libraries/System.Linq/src/System/Linq/Lookup.cs @@ -7,11 +7,43 @@ namespace System.Linq { + /// Provides a set of ( in Visual Basic) methods for querying objects that implement . + /// + /// The methods in this class provide an implementation of the standard query operators for querying data sources that implement . The standard query operators are general purpose methods that follow the LINQ pattern and enable you to express traversal, filter, and projection operations over data in any .NET-based programming language. + /// The majority of the methods in this class are defined as extension methods that extend . This means they can be called like an instance method on any object that implements . + /// Methods that are used in a query that returns a sequence of values do not consume the target data until the query object is enumerated. This is known as deferred execution. Methods that are used in a query that returns a singleton value execute and consume the target data immediately. + /// + /// Standard Query Operators Overview + /// Extension Methods (C# Programming Guide) + /// Extension Methods (Visual Basic) public static partial class Enumerable { + /// Creates a from an according to a specified key selector function. + /// The type of the elements of . + /// The type of the key returned by . + /// The to create a from. + /// A function to extract a key from each element. + /// A that contains keys and values. The values within each group are in the same order as in . + /// or is . + /// + /// The method returns a , a one-to-many dictionary that maps keys to collections of values. A differs from a , which performs a one-to-one mapping of keys to single values. + /// The default equality comparer is used to compare keys. + /// public static ILookup ToLookup(this IEnumerable source, Func keySelector) => ToLookup(source, keySelector, null); + /// Creates a from an according to a specified key selector function and key comparer. + /// The type of the elements of . + /// The type of the key returned by . + /// The to create a from. + /// A function to extract a key from each element. + /// An to compare keys. + /// A that contains keys and values. The values within each group are in the same order as in . + /// or is . + /// + /// The method returns a , a one-to-many dictionary that maps keys to collections of values. A is different to a , which performs a one-to-one mapping of keys to single values. + /// If is , the default equality comparer is used to compare keys. + /// public static ILookup ToLookup(this IEnumerable source, Func keySelector, IEqualityComparer? comparer) { if (source == null) @@ -27,9 +59,39 @@ public static ILookup ToLookup(this IEnumerable.Create(source, keySelector, comparer); } + /// Creates a from an according to specified key selector and element selector functions. + /// The type of the elements of . + /// The type of the key returned by . + /// The type of the value returned by . + /// The to create a from. + /// A function to extract a key from each element. + /// A transform function to produce a result element value from each element. + /// A that contains values of type selected from the input sequence. + /// or or is . + /// + /// The method returns a , a one-to-many dictionary that maps keys to collections of values. A differs from a , which performs a one-to-one mapping of keys to single values. + /// The default equality comparer is used to compare keys. + /// + /// The following code example demonstrates how to use to create a by using a key selector function and an element selector function. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet107"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet107"::: public static ILookup ToLookup(this IEnumerable source, Func keySelector, Func elementSelector) => ToLookup(source, keySelector, elementSelector, null); + /// Creates a from an according to a specified key selector function, a comparer and an element selector function. + /// The type of the elements of . + /// The type of the key returned by . + /// The type of the value returned by . + /// The to create a from. + /// A function to extract a key from each element. + /// A transform function to produce a result element value from each element. + /// An to compare keys. + /// A that contains values of type selected from the input sequence. + /// or or is . + /// + /// The method returns a , a one-to-many dictionary that maps keys to collections of values. A differs from a , which performs a one-to-one mapping of keys to single values. + /// If is , the default equality comparer is used to compare keys. + /// public static ILookup ToLookup(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer? comparer) { if (source == null) @@ -51,15 +113,43 @@ public static ILookup ToLookup(this IEn } } + /// Defines an indexer, size property, and Boolean search method for data structures that map keys to sequences of values. + /// The type of the keys in the . + /// The type of the elements in the sequences that make up the values in the . + /// + /// The type implements the interface. + /// The extension method , which can be appended to the end of a LINQ query, returns an object of type . + /// + /// The following code example creates an object and iterates through its contents. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.ILookup/cs/ILookup.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.ILookup/vb/ILookup.vb" id="Snippet1"::: + /// public interface ILookup : IEnumerable> { + /// Gets the number of key/value collection pairs in the . + /// The number of key/value collection pairs in the . int Count { get; } IEnumerable this[TKey key] { get; } + /// Determines whether a specified key exists in the . + /// The key to search for in the . + /// if is in the ; otherwise, . bool Contains(TKey key); } + /// Represents a collection of keys each mapped to one or more values. + /// The type of the keys in the . + /// The type of the elements of each value in the . + /// A resembles a . The difference is that a maps keys to single values, whereas a maps keys to collections of values. + /// You can create an instance of a by calling on an object that implements . + /// [!NOTE] + /// > There is no public constructor to create a new instance of a . Additionally, objects are immutable, that is, you cannot add or remove elements or keys from a object after it has been created. + /// ]]> + /// The following example creates a from a collection of objects. It then enumerates the and outputs each key and each value in the key's associated collection of values. It also demonstrates how to use the properties and and the methods and . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Lookup/CS/lookup.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Lookup/VB/Lookup.vb" id="Snippet1"::: [DebuggerDisplay("Count = {Count}")] [DebuggerTypeProxy(typeof(SystemLinq_LookupDebugView<,>))] public partial class Lookup : ILookup @@ -119,6 +209,12 @@ private Lookup(IEqualityComparer? comparer) _groupings = new Grouping[7]; } + /// Gets the number of key/value collection pairs in the . + /// The number of key/value collection pairs in the . + /// The value of the property does not change because items cannot be added to or removed from a object after it has been created. + /// The following example demonstrates how to use to determine the number of key/value collection pairs in a . This code example is part of a larger example provided for the class. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Lookup/CS/lookup.cs" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Lookup/VB/Lookup.vb" id="Snippet2"::: public int Count => _count; public IEnumerable this[TKey key] @@ -130,8 +226,21 @@ public IEnumerable this[TKey key] } } + /// Determines whether a specified key is in the . + /// The key to find in the . + /// if is in the ; otherwise, . + /// + /// The following example demonstrates how to use to determine whether a contains a specified key. This code example is part of a larger example provided for the class. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Lookup/CS/lookup.cs" id="Snippet4"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Lookup/VB/Lookup.vb" id="Snippet4"::: public bool Contains(TKey key) => GetGrouping(key, create: false) != null; + /// Returns a generic enumerator that iterates through the . + /// An enumerator for the . + /// + /// The following example demonstrates how to use to iterate through the keys and values of a . This code example is part of a larger example provided for the class. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Lookup/CS/lookup.cs" id="Snippet5"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Lookup/VB/Lookup.vb" id="Snippet5"::: public IEnumerator> GetEnumerator() { Grouping? g = _lastGrouping; @@ -168,6 +277,10 @@ internal List ToList(Func, TResult return list; } + /// Applies a transform function to each key and its associated values and returns the results. + /// The type of the result values produced by . + /// A function to project a result value from each key and its associated values. + /// A collection that contains one value for each key/value collection pair in the . public IEnumerable ApplyResultSelector(Func, TResult> resultSelector) { Grouping? g = _lastGrouping; @@ -185,6 +298,9 @@ public IEnumerable ApplyResultSelector(FuncReturns an enumerator that iterates through the . This class cannot be inherited. + /// An enumerator for the . + /// This member is an explicit interface member implementation. It can be used only when the instance is cast to an interface. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); private int InternalGetHashCode(TKey key) diff --git a/src/libraries/System.Linq/src/System/Linq/Max.cs b/src/libraries/System.Linq/src/System/Linq/Max.cs index 8e9f918d0724cb..2396dbce7baceb 100644 --- a/src/libraries/System.Linq/src/System/Linq/Max.cs +++ b/src/libraries/System.Linq/src/System/Linq/Max.cs @@ -8,6 +8,16 @@ namespace System.Linq { public static partial class Enumerable { + /// Returns the maximum value in a sequence of values. + /// A sequence of values to determine the maximum value of. + /// The maximum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static int Max(this IEnumerable source) { if (source == null) @@ -37,6 +47,16 @@ public static int Max(this IEnumerable source) return value; } + /// Returns the maximum value in a sequence of nullable values. + /// A sequence of nullable values to determine the maximum value of. + /// A value of type Nullable<Int32> in C# or Nullable(Of Int32) in Visual Basic that corresponds to the maximum value in the sequence. + /// is . + /// + /// The method uses the implementation of to compare values. + /// If the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static int? Max(this IEnumerable source) { if (source == null) @@ -99,6 +119,19 @@ public static int Max(this IEnumerable source) return value; } + /// Returns the maximum value in a sequence of values. + /// A sequence of values to determine the maximum value of. + /// The maximum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine the maximum value in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet52"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet52"::: + /// Aggregate Clause (Visual Basic) public static long Max(this IEnumerable source) { if (source == null) @@ -128,6 +161,16 @@ public static long Max(this IEnumerable source) return value; } + /// Returns the maximum value in a sequence of nullable values. + /// A sequence of nullable values to determine the maximum value of. + /// A value of type Nullable<Int64> in C# or Nullable(Of Int64) in Visual Basic that corresponds to the maximum value in the sequence. + /// is . + /// + /// The method uses the implementation of to compare values. + /// If the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static long? Max(this IEnumerable source) { if (source == null) @@ -184,6 +227,16 @@ public static long Max(this IEnumerable source) return value; } + /// Returns the maximum value in a sequence of values. + /// A sequence of values to determine the maximum value of. + /// The maximum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static double Max(this IEnumerable source) { if (source == null) @@ -228,6 +281,19 @@ public static double Max(this IEnumerable source) return value; } + /// Returns the maximum value in a sequence of nullable values. + /// A sequence of nullable values to determine the maximum value of. + /// A value of type Nullable<Double> in C# or Nullable(Of Double) in Visual Basic that corresponds to the maximum value in the sequence. + /// is . + /// + /// The method uses the implementation of to compare values. + /// If the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine the maximum value in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet54"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet54"::: + /// Aggregate Clause (Visual Basic) public static double? Max(this IEnumerable source) { if (source == null) @@ -282,6 +348,16 @@ public static double Max(this IEnumerable source) return value; } + /// Returns the maximum value in a sequence of values. + /// A sequence of values to determine the maximum value of. + /// The maximum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static float Max(this IEnumerable source) { if (source == null) @@ -321,6 +397,16 @@ public static float Max(this IEnumerable source) return value; } + /// Returns the maximum value in a sequence of nullable values. + /// A sequence of nullable values to determine the maximum value of. + /// A value of type Nullable<Single> in C# or Nullable(Of Single) in Visual Basic that corresponds to the maximum value in the sequence. + /// is . + /// + /// The method uses the implementation of to compare values. + /// If the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static float? Max(this IEnumerable source) { if (source == null) @@ -375,6 +461,16 @@ public static float Max(this IEnumerable source) return value; } + /// Returns the maximum value in a sequence of values. + /// A sequence of values to determine the maximum value of. + /// The maximum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static decimal Max(this IEnumerable source) { if (source == null) @@ -404,6 +500,16 @@ public static decimal Max(this IEnumerable source) return value; } + /// Returns the maximum value in a sequence of nullable values. + /// A sequence of nullable values to determine the maximum value of. + /// A value of type Nullable<Decimal> in C# or Nullable(Of Decimal) in Visual Basic that corresponds to the maximum value in the sequence. + /// is . + /// + /// The method uses the implementation of to compare values. + /// If the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static decimal? Max(this IEnumerable source) { if (source == null) @@ -441,7 +547,35 @@ public static decimal Max(this IEnumerable source) return value; } + /// Returns the maximum value in a generic sequence. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// The maximum value in the sequence. + /// is . + /// No object in implements the or interface. + /// + /// If type implements , the method uses that implementation to compare values. Otherwise, if type implements , that implementation is used to compare values. + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine the maximum value in a sequence of objects. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet57"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet57"::: + /// Aggregate Clause (Visual Basic) public static TSource? Max(this IEnumerable source) => Max(source, comparer: null); + + /// Returns the maximum value in a generic sequence. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// The to compare values. + /// The maximum value in the sequence. + /// is . + /// No object in implements the or interface. + /// + /// If type implements , the method uses that implementation to compare values. Otherwise, if type implements , that implementation is used to compare values. + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// public static TSource? Max(this IEnumerable source, IComparer? comparer) { if (source == null) @@ -512,7 +646,31 @@ public static decimal Max(this IEnumerable source) return value; } + /// Returns the maximum value in a generic sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the maximum value of. + /// A function to extract the key for each element. + /// The value with the maximum key in the sequence. + /// is . + /// No key extracted from implements the or interface. + /// + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// public static TSource? MaxBy(this IEnumerable source, Func keySelector) => MaxBy(source, keySelector, null); + + /// Returns the maximum value in a generic sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the maximum value of. + /// A function to extract the key for each element. + /// The to compare keys. + /// The value with the maximum key in the sequence. + /// is . + /// No key extracted from implements the or interface. + /// + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// public static TSource? MaxBy(this IEnumerable source, Func keySelector, IComparer? comparer) { if (source == null) @@ -597,6 +755,22 @@ public static decimal Max(this IEnumerable source) return value; } + /// Invokes a transform function on each element of a sequence and returns the maximum value. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The maximum value in the sequence. + /// or is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, , that projects the members of into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// Aggregate Clause (Visual Basic) public static int Max(this IEnumerable source, Func selector) { if (source == null) @@ -631,6 +805,23 @@ public static int Max(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the maximum nullable value. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The value of type Nullable<Int32> in C# or Nullable(Of Int32) in Visual Basic that corresponds to the maximum value in the sequence. + /// or is . + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically `Nullable` in C# or `Nullable(Of Int32)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static int? Max(this IEnumerable source, Func selector) { if (source == null) @@ -698,6 +889,24 @@ public static int Max(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the maximum value. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The maximum value in the sequence. + /// or is . + /// contains no elements. + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static long Max(this IEnumerable source, Func selector) { if (source == null) @@ -732,6 +941,23 @@ public static long Max(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the maximum nullable value. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The value of type Nullable<Int64> in C# or Nullable(Of Int64) in Visual Basic that corresponds to the maximum value in the sequence. + /// or is . + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically `Nullable` in C# or `Nullable(Of Int64)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static long? Max(this IEnumerable source, Func selector) { if (source == null) @@ -793,6 +1019,24 @@ public static long Max(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the maximum value. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The maximum value in the sequence. + /// or is . + /// contains no elements. + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static float Max(this IEnumerable source, Func selector) { if (source == null) @@ -837,6 +1081,23 @@ public static float Max(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the maximum nullable value. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The value of type Nullable<Single> in C# or Nullable(Of Single) in Visual Basic that corresponds to the maximum value in the sequence. + /// or is . + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically `Nullable` in C# or `Nullable(Of Single)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static float? Max(this IEnumerable source, Func selector) { if (source == null) @@ -896,6 +1157,24 @@ public static float Max(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the maximum value. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The maximum value in the sequence. + /// or is . + /// contains no elements. + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static double Max(this IEnumerable source, Func selector) { if (source == null) @@ -945,6 +1224,23 @@ public static double Max(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the maximum nullable value. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The value of type Nullable<Double> in C# or Nullable(Of Double) in Visual Basic that corresponds to the maximum value in the sequence. + /// or is . + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically `Nullable` in C# or `Nullable(Of Double)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static double? Max(this IEnumerable source, Func selector) { if (source == null) @@ -1004,6 +1300,24 @@ public static double Max(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the maximum value. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The maximum value in the sequence. + /// or is . + /// contains no elements. + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static decimal Max(this IEnumerable source, Func selector) { if (source == null) @@ -1038,6 +1352,23 @@ public static decimal Max(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the maximum nullable value. + /// The type of the elements of . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The value of type Nullable<Decimal> in C# or Nullable(Of Decimal) in Visual Basic that corresponds to the maximum value in the sequence. + /// or is . + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically `Nullable` in C# or `Nullable(Of Decimal)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static decimal? Max(this IEnumerable source, Func selector) { if (source == null) @@ -1080,6 +1411,23 @@ public static decimal Max(this IEnumerable source, FuncInvokes a transform function on each element of a generic sequence and returns the maximum resulting value. + /// The type of the elements of . + /// The type of the value returned by . + /// A sequence of values to determine the maximum value of. + /// A transform function to apply to each element. + /// The maximum value in the sequence. + /// or is . + /// , this method uses that implementation to compare values. Otherwise, if type `TResult` implements , that implementation is used to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the maximum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet58"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet58"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static TResult? Max(this IEnumerable source, Func selector) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Min.cs b/src/libraries/System.Linq/src/System/Linq/Min.cs index fb90cdf348143a..de0b118576ab54 100644 --- a/src/libraries/System.Linq/src/System/Linq/Min.cs +++ b/src/libraries/System.Linq/src/System/Linq/Min.cs @@ -8,6 +8,16 @@ namespace System.Linq { public static partial class Enumerable { + /// Returns the minimum value in a sequence of values. + /// A sequence of values to determine the minimum value of. + /// The minimum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static int Min(this IEnumerable source) { if (source == null) @@ -37,6 +47,19 @@ public static int Min(this IEnumerable source) return value; } + /// Returns the minimum value in a sequence of nullable values. + /// A sequence of nullable values to determine the minimum value of. + /// A value of type Nullable<Int32> in C# or Nullable(Of Int32) in Visual Basic that corresponds to the minimum value in the sequence. + /// is . + /// + /// The method uses the implementation of to compare values. + /// If the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine the minimum value in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet63"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet63"::: + /// Aggregate Clause (Visual Basic) public static int? Min(this IEnumerable source) { if (source == null) @@ -81,6 +104,16 @@ public static int Min(this IEnumerable source) return value; } + /// Returns the minimum value in a sequence of values. + /// A sequence of values to determine the minimum value of. + /// The minimum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static long Min(this IEnumerable source) { if (source == null) @@ -110,6 +143,16 @@ public static long Min(this IEnumerable source) return value; } + /// Returns the minimum value in a sequence of nullable values. + /// A sequence of nullable values to determine the minimum value of. + /// A value of type Nullable<Int64> in C# or Nullable(Of Int64) in Visual Basic that corresponds to the minimum value in the sequence. + /// is . + /// + /// The method uses the implementation of to compare values. + /// If the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static long? Min(this IEnumerable source) { if (source == null) @@ -150,6 +193,16 @@ public static long Min(this IEnumerable source) return value; } + /// Returns the minimum value in a sequence of values. + /// A sequence of values to determine the minimum value of. + /// The minimum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static float Min(this IEnumerable source) { if (source == null) @@ -197,6 +250,16 @@ public static float Min(this IEnumerable source) return value; } + /// Returns the minimum value in a sequence of nullable values. + /// A sequence of nullable values to determine the minimum value of. + /// A value of type Nullable<Single> in C# or Nullable(Of Single) in Visual Basic that corresponds to the minimum value in the sequence. + /// is . + /// + /// The method uses the implementation of to compare values. + /// If the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static float? Min(this IEnumerable source) { if (source == null) @@ -246,6 +309,19 @@ public static float Min(this IEnumerable source) return value; } + /// Returns the minimum value in a sequence of values. + /// A sequence of values to determine the minimum value of. + /// The minimum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine the minimum value in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet60"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet60"::: + /// Aggregate Clause (Visual Basic) public static double Min(this IEnumerable source) { if (source == null) @@ -284,6 +360,16 @@ public static double Min(this IEnumerable source) return value; } + /// Returns the minimum value in a sequence of nullable values. + /// A sequence of nullable values to determine the minimum value of. + /// A value of type Nullable<Double> in C# or Nullable(Of Double) in Visual Basic that corresponds to the minimum value in the sequence. + /// is . + /// + /// The method uses the implementation of to compare values. + /// If the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static double? Min(this IEnumerable source) { if (source == null) @@ -333,6 +419,16 @@ public static double Min(this IEnumerable source) return value; } + /// Returns the minimum value in a sequence of values. + /// A sequence of values to determine the minimum value of. + /// The minimum value in the sequence. + /// is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static decimal Min(this IEnumerable source) { if (source == null) @@ -362,6 +458,16 @@ public static decimal Min(this IEnumerable source) return value; } + /// Returns the minimum value in a sequence of nullable values. + /// A sequence of nullable values to determine the minimum value of. + /// A value of type Nullable<Decimal> in C# or Nullable(Of Decimal) in Visual Basic that corresponds to the minimum value in the sequence. + /// is . + /// + /// The method uses the implementation of to compare values. + /// If the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static decimal? Min(this IEnumerable source) { if (source == null) @@ -399,7 +505,35 @@ public static decimal Min(this IEnumerable source) return value; } + /// Returns the minimum value in a generic sequence. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// The minimum value in the sequence. + /// is . + /// No object in implements the or interface. + /// + /// If type implements , this method uses that implementation to compare values. Otherwise, if type implements , that implementation is used to compare values. + /// If is a reference type and the source sequence is empty or contains only values that are , this function returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine the minimum value in a sequence of objects. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet67"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet67"::: + /// Aggregate Clause (Visual Basic) public static TSource? Min(this IEnumerable source) => Min(source, comparer: null); + + /// Returns the minimum value in a generic sequence. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// The to compare values. + /// The minimum value in the sequence. + /// is . + /// No object in implements the or interface. + /// + /// If type implements , the method uses that implementation to compare values. Otherwise, if type implements , that implementation is used to compare values. + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// In Visual Basic query expression syntax, an `Aggregate Into Max()` clause translates to an invocation of . + /// public static TSource? Min(this IEnumerable source, IComparer? comparer) { if (source == null) @@ -470,7 +604,31 @@ public static decimal Min(this IEnumerable source) return value; } + /// Returns the minimum value in a generic sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the minimum value of. + /// A function to extract the key for each element. + /// The value with the minimum key in the sequence. + /// is . + /// No key extracted from implements the or interface. + /// + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// public static TSource? MinBy(this IEnumerable source, Func keySelector) => MinBy(source, keySelector, comparer: null); + + /// Returns the minimum value in a generic sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the minimum value of. + /// A function to extract the key for each element. + /// The to compare keys. + /// The value with the minimum key in the sequence. + /// is . + /// No key extracted from implements the or interface. + /// + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// public static TSource? MinBy(this IEnumerable source, Func keySelector, IComparer? comparer) { if (source == null) @@ -555,6 +713,22 @@ public static decimal Min(this IEnumerable source) return value; } + /// Invokes a transform function on each element of a sequence and returns the minimum value. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The minimum value in the sequence. + /// or is . + /// contains no elements. + /// + /// The method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, , that projects the members of into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// Aggregate Clause (Visual Basic) public static int Min(this IEnumerable source, Func selector) { if (source == null) @@ -589,6 +763,23 @@ public static int Min(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the minimum nullable value. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The value of type Nullable<Int32> in C# or Nullable(Of Int32) in Visual Basic that corresponds to the minimum value in the sequence. + /// or is . + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of source into a numeric type, specifically `Nullable` in C# or `Nullable(Of Int32)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static int? Min(this IEnumerable source, Func selector) { if (source == null) @@ -638,6 +829,24 @@ public static int Min(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the minimum value. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The minimum value in the sequence. + /// or is . + /// contains no elements. + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static long Min(this IEnumerable source, Func selector) { if (source == null) @@ -672,6 +881,23 @@ public static long Min(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the minimum nullable value. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The value of type Nullable<Int64> in C# or Nullable(Of Int64) in Visual Basic that corresponds to the minimum value in the sequence. + /// or is . + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically `Nullable` in C# or `Nullable(Of Int64)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static long? Min(this IEnumerable source, Func selector) { if (source == null) @@ -717,6 +943,24 @@ public static long Min(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the minimum value. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The minimum value in the sequence. + /// or is . + /// contains no elements. + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static float Min(this IEnumerable source, Func selector) { if (source == null) @@ -769,6 +1013,23 @@ public static float Min(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the minimum nullable value. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The value of type Nullable<Single> in C# or Nullable(Of Single) in Visual Basic that corresponds to the minimum value in the sequence. + /// or is . + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically `Nullable` in C# or `Nullable(Of Single)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static float? Min(this IEnumerable source, Func selector) { if (source == null) @@ -823,6 +1084,24 @@ public static float Min(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the minimum value. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The minimum value in the sequence. + /// or is . + /// contains no elements. + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static double Min(this IEnumerable source, Func selector) { if (source == null) @@ -866,6 +1145,23 @@ public static double Min(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the minimum nullable value. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The value of type Nullable<Double> in C# or Nullable(Of Double) in Visual Basic that corresponds to the minimum value in the sequence. + /// or is . + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically `Nullable` in C# or `Nullable(Of Double)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static double? Min(this IEnumerable source, Func selector) { if (source == null) @@ -920,6 +1216,24 @@ public static double Min(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the minimum value. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The minimum value in the sequence. + /// or is . + /// contains no elements. + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static decimal Min(this IEnumerable source, Func selector) { if (source == null) @@ -954,6 +1268,23 @@ public static decimal Min(this IEnumerable source, FuncInvokes a transform function on each element of a sequence and returns the minimum nullable value. + /// The type of the elements of . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The value of type Nullable<Decimal> in C# or Nullable(Of Decimal) in Visual Basic that corresponds to the minimum value in the sequence. + /// or is . + /// method uses the implementation of to compare values. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically `Nullable` in C# or `Nullable(Of Decimal)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static decimal? Min(this IEnumerable source, Func selector) { if (source == null) @@ -996,6 +1327,23 @@ public static decimal Min(this IEnumerable source, FuncInvokes a transform function on each element of a generic sequence and returns the minimum resulting value. + /// The type of the elements of . + /// The type of the value returned by . + /// A sequence of values to determine the minimum value of. + /// A transform function to apply to each element. + /// The minimum value in the sequence. + /// or is . + /// , this method uses that implementation to compare values. Otherwise, if type `TResult` implements , that implementation is used to compare values. + /// In Visual Basic query expression syntax, an `Aggregate Into Min()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to determine the minimum value in a sequence of projected values. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet68"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet68"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static TResult? Min(this IEnumerable source, Func selector) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/OrderBy.cs b/src/libraries/System.Linq/src/System/Linq/OrderBy.cs index e3e3dc313d5378..91fadaed62a457 100644 --- a/src/libraries/System.Linq/src/System/Linq/OrderBy.cs +++ b/src/libraries/System.Linq/src/System/Linq/OrderBy.cs @@ -7,18 +7,127 @@ namespace System.Linq { public static partial class Enumerable { + /// Sorts the elements of a sequence in ascending order according to a key. + /// The type of the elements of . + /// The type of the key returned by . + /// A sequence of values to order. + /// A function to extract a key from an element. + /// An whose elements are sorted according to a key. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// To order a sequence by the values of the elements themselves, specify the identity function (`x => x` in Visual C# or `Function(x) x` in Visual Basic) for . + /// Two methods are defined to extend the type , which is the return type of this method. These two methods, namely `ThenBy` and `ThenByDescending`, enable you to specify additional sort criteria to sort a sequence. `ThenBy` and `ThenByDescending` also return an , which means any number of consecutive calls to `ThenBy` or `ThenByDescending` can be made. + /// [!NOTE] + /// > Because inherits from , you can call or on the results of a call to , , or . Doing this introduces a new primary ordering that ignores the previously established ordering. + /// ]]> + /// This method compares keys by using the default comparer . + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the same key. + /// In query expression syntax, an `orderby` (Visual C#) or `Order By` (Visual Basic) clause translates to an invocation of . + /// The following code example demonstrates how to use to sort the elements of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet70"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet70"::: + /// + /// + /// orderby clause (C# Reference) + /// Order By Clause (Visual Basic) public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector) => new OrderedEnumerable(source, keySelector, null, false, null); + /// Sorts the elements of a sequence in ascending order by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by . + /// A sequence of values to order. + /// A function to extract a key from an element. + /// An to compare keys. + /// An whose elements are sorted according to a key. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// To order a sequence by the values of the elements themselves, specify the identity function (`x => x` in Visual C# or `Function(x) x` in Visual Basic) for . + /// Two methods are defined to extend the type , which is the return type of this method. These two methods, namely `ThenBy` and `ThenByDescending`, enable you to specify additional sort criteria to sort a sequence. `ThenBy` and `ThenByDescending` also return an , which means any number of consecutive calls to `ThenBy` or `ThenByDescending` can be made. + /// [!NOTE] + /// > Because inherits from , you can call or on the results of a call to , , or . Doing this introduces a new primary ordering that ignores the previously established ordering. + /// ]]> + /// If is , the default comparer is used to compare keys. + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the same key. + /// + /// public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, IComparer? comparer) => new OrderedEnumerable(source, keySelector, comparer, false, null); + /// Sorts the elements of a sequence in descending order according to a key. + /// The type of the elements of . + /// The type of the key returned by . + /// A sequence of values to order. + /// A function to extract a key from an element. + /// An whose elements are sorted in descending order according to a key. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// To order a sequence by the values of the elements themselves, specify the identity function (`x => x` in Visual C# or `Function(x) x` in Visual Basic) for . + /// For an example of this method, see . + /// Two methods are defined to extend the type , which is the return type of this method. These two methods, namely `ThenBy` and `ThenByDescending`, enable you to specify additional sort criteria to sort a sequence. `ThenBy` and `ThenByDescending` also return an , which means any number of consecutive calls to `ThenBy` or `ThenByDescending` can be made. + /// [!NOTE] + /// > Because inherits from , you can call or on the results of a call to , , or . Doing this introduces a new primary ordering that ignores the previously established ordering. + /// ]]> + /// This method compares keys by using the default comparer . + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the same key. + /// In query expression syntax, an `orderby descending` (Visual C#) or `Order By Descending` (Visual Basic) clause translates to an invocation of . + /// + /// + /// orderby clause (C# Reference) + /// Order By Clause (Visual Basic) public static IOrderedEnumerable OrderByDescending(this IEnumerable source, Func keySelector) => new OrderedEnumerable(source, keySelector, null, true, null); + /// Sorts the elements of a sequence in descending order by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by . + /// A sequence of values to order. + /// A function to extract a key from an element. + /// An to compare keys. + /// An whose elements are sorted in descending order according to a key. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// To order a sequence by the values of the elements themselves, specify the identity function (`x => x` in Visual C# or `Function(x) x` in Visual Basic) for . + /// Two methods are defined to extend the type , which is the return type of this method. These two methods, namely `ThenBy` and `ThenByDescending`, enable you to specify additional sort criteria to sort a sequence. `ThenBy` and `ThenByDescending` also return an , which means any number of consecutive calls to `ThenBy` or `ThenByDescending` can be made. + /// [!NOTE] + /// > Because inherits from , you can call or on the results of a call to , , or . Doing this introduces a new primary ordering that ignores the previously established ordering. + /// ]]> + /// If is , the default comparer is used to compare keys. + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the same key. + /// The following code example demonstrates how to use to sort the elements of a sequence in descending order by using a transform function and a custom comparer. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet71"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet71"::: + /// + /// public static IOrderedEnumerable OrderByDescending(this IEnumerable source, Func keySelector, IComparer? comparer) => new OrderedEnumerable(source, keySelector, comparer, true, null); + /// Performs a subsequent ordering of the elements in a sequence in ascending order according to a key. + /// The type of the elements of . + /// The type of the key returned by . + /// An that contains elements to sort. + /// A function to extract a key from each element. + /// An whose elements are sorted according to a key. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// To order a sequence by the values of the elements themselves, specify the identity function (`x => x` in Visual C# or `Function(x) x` in Visual Basic) for . + /// and are defined to extend the type , which is also the return type of these methods. This design enables you to specify multiple sort criteria by applying any number of or methods. + /// [!NOTE] + /// > Because inherits from , you can call or on the results of a call to , , or . Doing this introduces a new primary ordering that ignores the previously established ordering. + /// ]]> + /// This method compares keys by using the default comparer . + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the same key. + /// In query expression syntax, an `orderby [first criterion], [second criterion]` (Visual C#) or `Order By [first criterion], [second criterion]` (Visual Basic) clause translates to an invocation of . + /// The following code example demonstrates how to use to perform a secondary ordering of the elements in a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet102"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet102"::: + /// orderby clause (C# Reference) + /// Order By Clause (Visual Basic) public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector) { if (source == null) @@ -29,6 +138,23 @@ public static IOrderedEnumerable ThenBy(this IOrderedEnu return source.CreateOrderedEnumerable(keySelector, null, false); } + /// Performs a subsequent ordering of the elements in a sequence in ascending order by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by . + /// An that contains elements to sort. + /// A function to extract a key from each element. + /// An to compare keys. + /// An whose elements are sorted according to a key. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// To order a sequence by the values of the elements themselves, specify the identity function (`x => x` in Visual C# or `Function(x) x` in Visual Basic) for . + /// and are defined to extend the type , which is also the return type of these methods. This design enables you to specify multiple sort criteria by applying any number of or methods. + /// [!NOTE] + /// > Because inherits from , you can call or on the results of a call to , , or . Doing this introduces a new primary ordering that ignores the previously established ordering. + /// ]]> + /// If is , the default comparer is used to compare keys. + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the same key. public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, IComparer? comparer) { if (source == null) @@ -39,6 +165,26 @@ public static IOrderedEnumerable ThenBy(this IOrderedEnu return source.CreateOrderedEnumerable(keySelector, comparer, false); } + /// Performs a subsequent ordering of the elements in a sequence in descending order, according to a key. + /// The type of the elements of . + /// The type of the key returned by . + /// An that contains elements to sort. + /// A function to extract a key from each element. + /// An whose elements are sorted in descending order according to a key. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// To order a sequence by the values of the elements themselves, specify the identity function (`x => x` in Visual C# or `Function(x) x` in Visual Basic) for . + /// and are defined to extend the type , which is also the return type of these methods. This design enables you to specify multiple sort criteria by applying any number of or methods. + /// [!NOTE] + /// > Because inherits from , you can call or on the results of a call to , , or . Doing this introduces a new primary ordering that ignores the previously established ordering. + /// ]]> + /// This sorting method compares keys by using the default comparer . + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the same key. + /// In Visual C# query expression syntax, an `orderby [first criterion], [second criterion] descending` clause translates to an invocation of . + /// In Visual Basic query expression syntax, an `Order By [first criterion], [second criterion] Descending` clause translates to an invocation of . + /// orderby clause (C# Reference) + /// Order By Clause (Visual Basic) public static IOrderedEnumerable ThenByDescending(this IOrderedEnumerable source, Func keySelector) { if (source == null) @@ -49,6 +195,26 @@ public static IOrderedEnumerable ThenByDescending(this I return source.CreateOrderedEnumerable(keySelector, null, true); } + /// Performs a subsequent ordering of the elements in a sequence in descending order by using a specified comparer. + /// The type of the elements of . + /// The type of the key returned by . + /// An that contains elements to sort. + /// A function to extract a key from each element. + /// An to compare keys. + /// An whose elements are sorted in descending order according to a key. + /// or is . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// To order a sequence by the values of the elements themselves, specify the identity function (`x => x` in Visual C# or `Function(x) x` in Visual Basic) for . + /// and are defined to extend the type , which is also the return type of these methods. This design enables you to specify multiple sort criteria by applying any number of or methods. + /// [!NOTE] + /// > Because inherits from , you can call or on the results of a call to , , or . Doing this introduces a new primary ordering that ignores the previously established ordering. + /// ]]> + /// If is , the default comparer is used to compare keys. + /// This method performs a stable sort; that is, if the keys of two elements are equal, the order of the elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the same key. + /// The following code example demonstrates how to use to perform a secondary ordering of the elements in a sequence in descending order by using a custom comparer. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet103"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet103"::: public static IOrderedEnumerable ThenByDescending(this IOrderedEnumerable source, Func keySelector, IComparer? comparer) { if (source == null) @@ -60,8 +226,27 @@ public static IOrderedEnumerable ThenByDescending(this I } } + /// Represents a sorted sequence. + /// The type of the elements of the sequence. + /// + /// This type is enumerable because it inherits from . + /// The extension methods and operate on objects of type . An object of type can be obtained by calling one of the primary sort methods, or , which return an . and , the subordinate sort methods, in turn also return an object of type . This design allows for any number of consecutive calls to or , where each call performs a subordinate ordering on the sorted data returned from the previous call. + /// + /// The following example demonstrates how to perform a primary and secondary ordering on an array of strings. It also demonstrates that the resulting is enumerable. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.IOrderedEnumerable/CS/IOrderedEnumerable.cs" interactive="try-dotnet-method" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.IOrderedEnumerable/VB/IOrderedEnumerable.vb" id="Snippet1"::: public interface IOrderedEnumerable : IEnumerable { + /// Performs a subsequent ordering on the elements of an according to a key. + /// The type of the key produced by . + /// The used to extract the key for each element. + /// The used to compare keys for placement in the returned sequence. + /// to sort the elements in descending order; to sort the elements in ascending order. + /// An whose elements are sorted according to a key. + /// The functionality provided by this method is like that provided by or , depending on whether is or . They both perform a subordinate ordering of an already sorted sequence of type . + /// The following code example demonstrates how to use to perform a secondary ordering on an . + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.IOrderedEnumerable/CS/IOrderedEnumerable.cs" interactive="try-dotnet-method" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.IOrderedEnumerable/VB/IOrderedEnumerable.vb" id="Snippet2"::: IOrderedEnumerable CreateOrderedEnumerable(Func keySelector, IComparer? comparer, bool descending); } } diff --git a/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs index c46465f82547b3..87da3ce81cffa2 100644 --- a/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Partition.SpeedOpt.cs @@ -136,6 +136,15 @@ public IPartition Take(int count) public int GetCount(bool onlyIfCheap) => _source.GetCount(_minIndexInclusive, _maxIndexInclusive, onlyIfCheap); } + /// Provides a set of ( in Visual Basic) methods for querying objects that implement . + /// + /// The methods in this class provide an implementation of the standard query operators for querying data sources that implement . The standard query operators are general purpose methods that follow the LINQ pattern and enable you to express traversal, filter, and projection operations over data in any .NET-based programming language. + /// The majority of the methods in this class are defined as extension methods that extend . This means they can be called like an instance method on any object that implements . + /// Methods that are used in a query that returns a sequence of values do not consume the target data until the query object is enumerated. This is known as deferred execution. Methods that are used in a query that returns a singleton value execute and consume the target data immediately. + /// + /// Standard Query Operators Overview + /// Extension Methods (C# Programming Guide) + /// Extension Methods (Visual Basic) public static partial class Enumerable { /// diff --git a/src/libraries/System.Linq/src/System/Linq/Range.cs b/src/libraries/System.Linq/src/System/Linq/Range.cs index b4c0db5277722f..b6a9ec303ff03b 100644 --- a/src/libraries/System.Linq/src/System/Linq/Range.cs +++ b/src/libraries/System.Linq/src/System/Linq/Range.cs @@ -8,6 +8,17 @@ namespace System.Linq { public static partial class Enumerable { + /// Generates a sequence of integral numbers within a specified range. + /// The value of the first integer in the sequence. + /// The number of sequential integers to generate. + /// An IEnumerable<Int32> in C# or IEnumerable(Of Int32) in Visual Basic that contains a range of sequential integral numbers. + /// is less than 0. + /// -or- + /// + -1 is larger than . + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The following code example demonstrates how to use to generate a sequence of values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet72"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet72"::: public static IEnumerable Range(int start, int count) { long max = ((long)start) + count - 1; diff --git a/src/libraries/System.Linq/src/System/Linq/Repeat.cs b/src/libraries/System.Linq/src/System/Linq/Repeat.cs index 10d3d6bd3fe60e..e8c221a8b0de02 100644 --- a/src/libraries/System.Linq/src/System/Linq/Repeat.cs +++ b/src/libraries/System.Linq/src/System/Linq/Repeat.cs @@ -8,6 +8,16 @@ namespace System.Linq { public static partial class Enumerable { + /// Generates a sequence that contains one repeated value. + /// The type of the value to be repeated in the result sequence. + /// The value to be repeated. + /// The number of times to repeat the value in the generated sequence. + /// An that contains a repeated value. + /// is less than 0. + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The following code example demonstrates how to use to generate a sequence of a repeated value. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet73"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet73"::: public static IEnumerable Repeat(TResult element, int count) { if (count < 0) diff --git a/src/libraries/System.Linq/src/System/Linq/Reverse.cs b/src/libraries/System.Linq/src/System/Linq/Reverse.cs index c369e6b70f37c9..975108c09121f3 100644 --- a/src/libraries/System.Linq/src/System/Linq/Reverse.cs +++ b/src/libraries/System.Linq/src/System/Linq/Reverse.cs @@ -8,6 +8,18 @@ namespace System.Linq { public static partial class Enumerable { + /// Inverts the order of the elements in a sequence. + /// The type of the elements of . + /// A sequence of values to reverse. + /// A sequence whose elements correspond to those of the input sequence in reverse order. + /// is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// Unlike , this sorting method does not consider the actual values themselves in determining the order. Rather, it just returns the elements in the reverse order from which they are produced by the underlying source. + /// + /// The following code example demonstrates how to use to reverse the order of elements in an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet74"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet74"::: public static IEnumerable Reverse(this IEnumerable source) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Select.cs b/src/libraries/System.Linq/src/System/Linq/Select.cs index c3414ca776938b..403c6de7549d93 100644 --- a/src/libraries/System.Linq/src/System/Linq/Select.cs +++ b/src/libraries/System.Linq/src/System/Linq/Select.cs @@ -10,6 +10,23 @@ namespace System.Linq { public static partial class Enumerable { + /// Projects each element of a sequence into a new form. + /// The type of the elements of . + /// The type of the value returned by . + /// A sequence of values to invoke a transform function on. + /// A transform function to apply to each element. + /// An whose elements are the result of invoking the transform function on each element of . + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// This projection method requires the transform function, , to produce one value for each value in the source sequence, . If returns a value that is itself a collection, it is up to the consumer to traverse the subsequences manually. In such a situation, it might be better for your query to return a single coalesced sequence of values. To achieve this, use the method instead of . Although `SelectMany` works similarly to `Select`, it differs in that the transform function returns a collection that is then expanded by `SelectMany` before it is returned. + /// In query expression syntax, a `select` (Visual C#) or `Select` (Visual Basic) clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to project over a sequence of values. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet75"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet75"::: + /// select clause (C# Reference) + /// Select Clause (Visual Basic) public static IEnumerable Select( this IEnumerable source, Func selector) { @@ -61,6 +78,21 @@ public static IEnumerable Select( static partial void CreateSelectIPartitionIterator( Func selector, IPartition partition, [NotNull] ref IEnumerable? result); + /// Projects each element of a sequence into a new form by incorporating the element's index. + /// The type of the elements of . + /// The type of the value returned by . + /// A sequence of values to invoke a transform function on. + /// A transform function to apply to each source element; the second parameter of the function represents the index of the source element. + /// An whose elements are the result of invoking the transform function on each element of . + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The first argument to represents the element to process. The second argument to represents the zero-based index of that element in the source sequence. This can be useful if the elements are in a known order and you want to do something with an element at a particular index, for example. It can also be useful if you want to retrieve the index of one or more elements. + /// This projection method requires the transform function, , to produce one value for each value in the source sequence, . If returns a value that is itself a collection, it is up to the consumer to traverse the subsequences manually. In such a situation, it might be better for your query to return a single coalesced sequence of values. To achieve this, use the method instead of . Although `SelectMany` works similarly to `Select`, it differs in that the transform function returns a collection that is then expanded by `SelectMany` before it is returned. + /// + /// The following code example demonstrates how to use to project over a sequence of values and use the index of each element. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet76"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet76"::: public static IEnumerable Select(this IEnumerable source, Func selector) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/SelectMany.cs b/src/libraries/System.Linq/src/System/Linq/SelectMany.cs index 1baf8fcf18612e..30b41289e3bc0d 100644 --- a/src/libraries/System.Linq/src/System/Linq/SelectMany.cs +++ b/src/libraries/System.Linq/src/System/Linq/SelectMany.cs @@ -8,6 +8,23 @@ namespace System.Linq { public static partial class Enumerable { + /// Projects each element of a sequence to an and flattens the resulting sequences into one sequence. + /// The type of the elements of . + /// The type of the elements of the sequence returned by . + /// A sequence of values to project. + /// A transform function to apply to each element. + /// An whose elements are the result of invoking the one-to-many transform function on each element of the input sequence. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method enumerates the input sequence, uses a transform function to map each element to an , and then enumerates and yields the elements of each such object. That is, for each element of , is invoked and a sequence of values is returned. then flattens this two-dimensional collection of collections into a one-dimensional and returns it. For example, if a query uses to obtain the orders (of type `Order`) for each customer in a database, the result is of type `IEnumerable<Order>` in C# or `IEnumerable(Of Order)` in Visual Basic. If instead the query uses to obtain the orders, the collection of collections of orders is not combined and the result is of type `IEnumerable<List<Order>>` in C# or `IEnumerable(Of List(Of Order))` in Visual Basic. + /// In query expression syntax, each `from` clause (Visual C#) or `From` clause (Visual Basic) after the initial one translates to an invocation of . + /// + /// The following code example demonstrates how to use to perform a one-to-many projection over an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet77"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet77"::: + /// from clause (C# Reference) + /// From Clause (Visual Basic) public static IEnumerable SelectMany(this IEnumerable source, Func> selector) { if (source == null) @@ -23,6 +40,21 @@ public static IEnumerable SelectMany(this IEnumerable return new SelectManySingleSelectorIterator(source, selector); } + /// Projects each element of a sequence to an , and flattens the resulting sequences into one sequence. The index of each source element is used in the projected form of that element. + /// The type of the elements of . + /// The type of the elements of the sequence returned by . + /// A sequence of values to project. + /// A transform function to apply to each source element; the second parameter of the function represents the index of the source element. + /// An whose elements are the result of invoking the one-to-many transform function on each element of an input sequence. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method enumerates the input sequence, uses a transform function to map each element to an , and then enumerates and yields the elements of each such object. That is, for each element of , is invoked and a sequence of values is returned. then flattens this two-dimensional collection of collections into a one-dimensional and returns it. For example, if a query uses to obtain the orders (of type `Order`) for each customer in a database, the result is of type `IEnumerable<Order>` in C# or `IEnumerable(Of Order)` in Visual Basic. If instead the query uses to obtain the orders, the collection of collections of orders is not combined and the result is of type `IEnumerable<List<Order>>` in C# or `IEnumerable(Of List(Of Order))` in Visual Basic. + /// The first argument to represents the element to process. The second argument to represents the zero-based index of that element in the source sequence. This can be useful if the elements are in a known order and you want to do something with an element at a particular index, for example. It can also be useful if you want to retrieve the index of one or more elements. + /// + /// The following code example demonstrates how to use to perform a one-to-many projection over an array and use the index of each outer element. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet78"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet78"::: public static IEnumerable SelectMany(this IEnumerable source, Func> selector) { if (source == null) @@ -55,6 +87,19 @@ private static IEnumerable SelectManyIterator(IEnumer } } + /// Projects each element of a sequence to an , flattens the resulting sequences into one sequence, and invokes a result selector function on each element therein. The index of each source element is used in the intermediate projected form of that element. + /// The type of the elements of . + /// The type of the intermediate elements collected by . + /// The type of the elements of the resulting sequence. + /// A sequence of values to project. + /// A transform function to apply to each source element; the second parameter of the function represents the index of the source element. + /// A transform function to apply to each element of the intermediate sequence. + /// An whose elements are the result of invoking the one-to-many transform function on each element of and then mapping each of those sequence elements and their corresponding source element to a result element. + /// or or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method is useful when you have to keep the elements of in scope for query logic that occurs after the call to . See the Example section for a code example. If there is a bidirectional relationship between objects of type and objects of type , that is, if an object of type provides a property to retrieve the object that produced it, you do not need this overload of . Instead, you can use and navigate back to the object through the object. + /// public static IEnumerable SelectMany(this IEnumerable source, Func> collectionSelector, Func resultSelector) { if (source == null) @@ -92,6 +137,25 @@ private static IEnumerable SelectManyIteratorProjects each element of a sequence to an , flattens the resulting sequences into one sequence, and invokes a result selector function on each element therein. + /// The type of the elements of . + /// The type of the intermediate elements collected by . + /// The type of the elements of the resulting sequence. + /// A sequence of values to project. + /// A transform function to apply to each element of the input sequence. + /// A transform function to apply to each element of the intermediate sequence. + /// An whose elements are the result of invoking the one-to-many transform function on each element of and then mapping each of those sequence elements and their corresponding source element to a result element. + /// or or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method is useful when you have to keep the elements of in scope for query logic that occurs after the call to . See the Example section for a code example. If there is a bidirectional relationship between objects of type and objects of type , that is, if an object of type provides a property to retrieve the object that produced it, you do not need this overload of . Instead, you can use and navigate back to the object through the object. + /// In query expression syntax, each `from` clause (Visual C#) or `From` clause (Visual Basic) after the initial one translates to an invocation of . + /// + /// The following code example demonstrates how to use to perform a one-to-many projection over an array and use a result selector function to keep each corresponding element from the source sequence in scope for the final call to `Select`. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet124"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet124"::: + /// from clause (C# Reference) + /// From Clause (Visual Basic) public static IEnumerable SelectMany(this IEnumerable source, Func> collectionSelector, Func resultSelector) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/SequenceEqual.cs b/src/libraries/System.Linq/src/System/Linq/SequenceEqual.cs index d1d6dc1586b0f5..c3c61eeee244be 100644 --- a/src/libraries/System.Linq/src/System/Linq/SequenceEqual.cs +++ b/src/libraries/System.Linq/src/System/Linq/SequenceEqual.cs @@ -7,9 +7,47 @@ namespace System.Linq { public static partial class Enumerable { + /// Determines whether two sequences are equal by comparing the elements by using the default equality comparer for their type. + /// The type of the elements of the input sequences. + /// An to compare to . + /// An to compare to the first sequence. + /// if the two source sequences are of equal length and their corresponding elements are equal according to the default equality comparer for their type; otherwise, . + /// or is . + /// + /// The method enumerates the two source sequences in parallel and compares corresponding elements by using the default equality comparer for , . + /// The default equality comparer, , is used to compare values of the types. + /// To compare a custom data type, you need to override the and the methods, and optionally implement the generic interface in the custom type. For more information, see the property. + /// + /// The following code examples demonstrate how to use to determine whether two sequences are equal. In the first two examples, the method determines whether the compared sequences contain references to the same objects. In the third and fourth examples, the method compares the actual data of the objects within the sequences. + /// In this example the sequences are equal. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet32"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet32"::: + /// The following code example compares two sequences that are not equal. Note that the sequences contain identical data, but because the objects that they contain have different references, the sequences are not considered equal. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet33"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet33"::: + /// If you want to compare the actual data of the objects in the sequences instead of just comparing their references, you have to implement the generic interface in your class. The following code example shows how to implement this interface in a helper class and provide and methods. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet9"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet9"::: + /// After you implement this interface, you can use sequences of `ProductA` objects in the method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet8"::: public static bool SequenceEqual(this IEnumerable first, IEnumerable second) => SequenceEqual(first, second, null); + /// Determines whether two sequences are equal by comparing their elements by using a specified . + /// The type of the elements of the input sequences. + /// An to compare to . + /// An to compare to the first sequence. + /// An to use to compare elements. + /// if the two source sequences are of equal length and their corresponding elements compare equal according to ; otherwise, . + /// or is . + /// The method enumerates the two source sequences in parallel and compares corresponding elements by using the specified . If is , the default equality comparer, , is used to compare elements. + /// The following example shows how to implement an equality comparer that can be used in the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet1"::: + /// After you implement this comparer, you can use sequences of `Product` objects in the method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet8"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet8"::: public static bool SequenceEqual(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) { if (first == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Single.cs b/src/libraries/System.Linq/src/System/Linq/Single.cs index 6455a841c9c46f..c7005393c8a8cc 100644 --- a/src/libraries/System.Linq/src/System/Linq/Single.cs +++ b/src/libraries/System.Linq/src/System/Linq/Single.cs @@ -8,6 +8,21 @@ namespace System.Linq { public static partial class Enumerable { + /// Returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence. + /// The type of the elements of . + /// An to return the single element of. + /// The single element of the input sequence. + /// is . + /// The input sequence contains more than one element. + /// -or- + /// The input sequence is empty. + /// The method throws an exception if the input sequence is empty. To instead return when the input sequence is empty, use . + /// The following code example demonstrates how to use to select the only element of an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet79"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet79"::: + /// The following code example demonstrates that throws an exception when the sequence does not contain exactly one element. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet80"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet80"::: public static TSource Single(this IEnumerable source) { TSource? single = source.TryGetSingle(out bool found); @@ -18,6 +33,24 @@ public static TSource Single(this IEnumerable source) return single!; } + /// Returns the only element of a sequence that satisfies a specified condition, and throws an exception if more than one such element exists. + /// The type of the elements of . + /// An to return a single element from. + /// A function to test an element for a condition. + /// The single element of the input sequence that satisfies a condition. + /// or is . + /// No element satisfies the condition in . + /// -or- + /// More than one element satisfies the condition in . + /// -or- + /// The source sequence is empty. + /// The method throws an exception if the input sequence contains no matching element. To instead return when no matching element is found, use . + /// The following code example demonstrates how to use to select the only element of an array that satisfies a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet81"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet81"::: + /// The following code example demonstrates that throws an exception when the sequence does not contain exactly one element that satisfies the condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet82"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet82"::: public static TSource Single(this IEnumerable source, Func predicate) { TSource? single = source.TryGetSingle(predicate, out bool found); @@ -29,18 +62,66 @@ public static TSource Single(this IEnumerable source, FuncReturns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. + /// The type of the elements of . + /// An to return the single element of. + /// The single element of the input sequence, or () if the sequence contains no elements. + /// is . + /// The input sequence contains more than one element. + /// + /// The default value for reference and nullable types is . + /// The method does not provide a way to specify a default value. If you want to specify a default value other than `default(TSource)`, use the method as described in the Example section. + /// + /// The following code example demonstrates how to use to select the only element of an array. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet83"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet83"::: + /// The following code example demonstrates that returns a default value when the sequence is empty. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet84"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet84"::: + /// Sometimes the value of `default(TSource)` is not the default value that you want to use if the collection contains no elements. Instead of checking the result for the unwanted default value and then changing it if necessary, you can use the method to specify the default value that you want to use if the collection is empty. Then, call to obtain the element. The following code example uses both techniques to obtain a default value of 1 if a collection of page numbers is empty. Because the default value for an integer is 0, which is not usually a valid page number, the default value must be specified as 1 instead. The first result variable is checked for the unwanted default value after the query has finished executing. The second result variable is obtained by using to specify a default value of 1. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet128"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet128"::: public static TSource? SingleOrDefault(this IEnumerable source) => source.TryGetSingle(out _); + /// Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. + /// The type of the elements of . + /// An to return the single element of. + /// The default value to return if the sequence is empty. + /// The single element of the input sequence, or if the sequence contains no elements. + /// is . + /// The input sequence contains more than one element. public static TSource SingleOrDefault(this IEnumerable source, TSource defaultValue) { var single = source.TryGetSingle(out bool found); return found ? single! : defaultValue; } + /// Returns the only element of a sequence that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. + /// The type of the elements of . + /// An to return a single element from. + /// A function to test an element for a condition. + /// The single element of the input sequence that satisfies the condition, or () if no such element is found. + /// or is . + /// More than one element satisfies the condition in . + /// The default value for reference and nullable types is . + /// The following code example demonstrates how to use to select the only element of an array that satisfies a condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet85"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet85"::: + /// The following code example demonstrates that returns a default value when the sequence contains no elements that satisfy the condition. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet86"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet86"::: public static TSource? SingleOrDefault(this IEnumerable source, Func predicate) => source.TryGetSingle(predicate, out _); + /// Returns the only element of a sequence that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. + /// The type of the elements of . + /// An to return a single element from. + /// A function to test an element for a condition. + /// The default value to return if the sequence is empty. + /// The single element of the input sequence that satisfies the condition, or if no such element is found. + /// or is . + /// More than one element satisfies the condition in . public static TSource SingleOrDefault(this IEnumerable source, Func predicate, TSource defaultValue) { var single = source.TryGetSingle(predicate, out bool found); diff --git a/src/libraries/System.Linq/src/System/Linq/Skip.cs b/src/libraries/System.Linq/src/System/Linq/Skip.cs index b6cf40526d1d0e..35782cb30b2943 100644 --- a/src/libraries/System.Linq/src/System/Linq/Skip.cs +++ b/src/libraries/System.Linq/src/System/Linq/Skip.cs @@ -8,6 +8,22 @@ namespace System.Linq { public static partial class Enumerable { + /// Bypasses a specified number of elements in a sequence and then returns the remaining elements. + /// The type of the elements of . + /// An to return elements from. + /// The number of elements to skip before returning the remaining elements. + /// An that contains the elements that occur after the specified index in the input sequence. + /// is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// If contains fewer than elements, an empty is returned. If is less than or equal to zero, all elements of are yielded. + /// The and methods are functional complements. Given a sequence `coll` and an integer `n`, concatenating the results of `coll.Take(n)` and `coll.Skip(n)` yields the same sequence as `coll`. + /// In Visual Basic query expression syntax, a `Skip` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to skip a specified number of elements in a sorted array and return the remaining elements. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet87"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet87"::: + /// Skip Clause (Visual Basic) public static IEnumerable Skip(this IEnumerable source, int count) { if (source == null) @@ -34,6 +50,23 @@ public static IEnumerable Skip(this IEnumerable sourc return SkipIterator(source, count); } + /// Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. + /// The type of the elements of . + /// An to return elements from. + /// A function to test each element for a condition. + /// An that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by . + /// or is . + /// + /// The method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// This method tests each element of by using and skips the element if the result is . After the predicate function returns for an element, that element and the remaining elements in are yielded and there are no more invocations of . + /// If returns for all elements in the sequence, an empty is returned. + /// The and methods are functional complements. Given a sequence `coll` and a pure function `p`, concatenating the results of `coll.TakeWhile(p)` and `coll.SkipWhile(p)` yields the same sequence as `coll`. + /// In Visual Basic query expression syntax, a `Skip While` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to skip elements of an array as long as a condition is true. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet88"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet88"::: + /// Skip While Clause (Visual Basic) public static IEnumerable SkipWhile(this IEnumerable source, Func predicate) { if (source == null) @@ -70,6 +103,24 @@ private static IEnumerable SkipWhileIterator(IEnumerableBypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. The element's index is used in the logic of the predicate function. + /// The type of the elements of . + /// An to return elements from. + /// A function to test each source element for a condition; the second parameter of the function represents the index of the source element. + /// An that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by . + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method tests each element of by using and skips the element if the result is . After the predicate function returns for an element, that element and the remaining elements in are yielded and there are no more invocations of . + /// If returns for all elements in the sequence, an empty is returned. + /// The first argument of represents the element to test. The second argument represents the zero-based index of the element within . + /// The and methods are functional complements. Given a sequence `coll` and a pure function `p`, concatenating the results of `coll.TakeWhile(p)` and `coll.SkipWhile(p)` yields the same sequence as `coll`. + /// In Visual Basic query expression syntax, a `Skip While` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to skip elements of an array as long as a condition that depends on the element's index is true. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet89"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet89"::: + /// Skip While Clause (Visual Basic) public static IEnumerable SkipWhile(this IEnumerable source, Func predicate) { if (source == null) @@ -112,6 +163,13 @@ private static IEnumerable SkipWhileIterator(IEnumerableReturns a new enumerable collection that contains the elements from with the last elements of the source collection omitted. + /// The type of the elements in the enumerable collection. + /// An enumerable collection instance. + /// The number of elements to omit from the end of the collection. + /// A new enumerable collection that contains the elements from minus elements from the end of the collection. + /// is . + /// If is not a positive number, this method returns an identical copy of the enumerable collection. public static IEnumerable SkipLast(this IEnumerable source, int count) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Sum.cs b/src/libraries/System.Linq/src/System/Linq/Sum.cs index ece04bc8a27e9c..38050a74074e4e 100644 --- a/src/libraries/System.Linq/src/System/Linq/Sum.cs +++ b/src/libraries/System.Linq/src/System/Linq/Sum.cs @@ -7,6 +7,16 @@ namespace System.Linq { public static partial class Enumerable { + /// Computes the sum of a sequence of values. + /// A sequence of values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// This method returns zero if contains no elements. + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static int Sum(this IEnumerable source) { if (source == null) @@ -26,6 +36,17 @@ public static int Sum(this IEnumerable source) return sum; } + /// Computes the sum of a sequence of nullable values. + /// A sequence of nullable values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// This method returns zero if contains no elements. + /// The result does not include values that are . + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static int? Sum(this IEnumerable source) { if (source == null) @@ -48,6 +69,16 @@ public static int Sum(this IEnumerable source) return sum; } + /// Computes the sum of a sequence of values. + /// A sequence of values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// This method returns zero if contains no elements. + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static long Sum(this IEnumerable source) { if (source == null) @@ -67,6 +98,17 @@ public static long Sum(this IEnumerable source) return sum; } + /// Computes the sum of a sequence of nullable values. + /// A sequence of nullable values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// This method returns zero if contains no elements. + /// The result does not include values that are . + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static long? Sum(this IEnumerable source) { if (source == null) @@ -89,6 +131,18 @@ public static long Sum(this IEnumerable source) return sum; } + /// Computes the sum of a sequence of values. + /// A sequence of values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// + /// This method returns zero if contains no elements. + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to sum the values of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet120"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet120"::: + /// Aggregate Clause (Visual Basic) public static float Sum(this IEnumerable source) { if (source == null) @@ -105,6 +159,19 @@ public static float Sum(this IEnumerable source) return (float)sum; } + /// Computes the sum of a sequence of nullable values. + /// A sequence of nullable values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// + /// This method returns zero if contains no elements. + /// The result does not include values that are . + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to sum the values of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet121"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet121"::: + /// Aggregate Clause (Visual Basic) public static float? Sum(this IEnumerable source) { if (source == null) @@ -124,6 +191,15 @@ public static float Sum(this IEnumerable source) return (float)sum; } + /// Computes the sum of a sequence of values. + /// A sequence of values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// + /// This method returns zero if contains no elements. + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static double Sum(this IEnumerable source) { if (source == null) @@ -140,6 +216,16 @@ public static double Sum(this IEnumerable source) return sum; } + /// Computes the sum of a sequence of nullable values. + /// A sequence of nullable values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// + /// This method returns zero if contains no elements. + /// The result does not include values that are . + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static double? Sum(this IEnumerable source) { if (source == null) @@ -159,6 +245,16 @@ public static double Sum(this IEnumerable source) return sum; } + /// Computes the sum of a sequence of values. + /// A sequence of values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// The method returns zero if contains no elements. + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static decimal Sum(this IEnumerable source) { if (source == null) @@ -175,6 +271,17 @@ public static decimal Sum(this IEnumerable source) return sum; } + /// Computes the sum of a sequence of nullable values. + /// A sequence of nullable values to calculate the sum of. + /// The sum of the values in the sequence. + /// is . + /// The sum is larger than . + /// + /// This method returns zero if contains no elements. + /// The result doesnot include values that are . + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// Aggregate Clause (Visual Basic) public static decimal? Sum(this IEnumerable source) { if (source == null) @@ -194,6 +301,24 @@ public static decimal Sum(this IEnumerable source) return sum; } + /// Computes the sum of the sequence of values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate a sum. + /// A transform function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// . + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet98"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static int Sum(this IEnumerable source, Func selector) { if (source == null) @@ -218,6 +343,25 @@ public static int Sum(this IEnumerable source, FuncComputes the sum of the sequence of nullable values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate a sum. + /// A transform function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// ` in C# or `Nullable(Of Int32)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet98"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static int? Sum(this IEnumerable source, Func selector) { if (source == null) @@ -246,6 +390,24 @@ public static int Sum(this IEnumerable source, FuncComputes the sum of the sequence of values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate a sum. + /// A transform function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// . + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet98"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static long Sum(this IEnumerable source, Func selector) { if (selector == null) @@ -270,6 +432,25 @@ public static long Sum(this IEnumerable source, FuncComputes the sum of the sequence of nullable values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate a sum. + /// A transform function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// ` in C# or `Nullable(Of Int64)` in Visual Basic + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet98"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static long? Sum(this IEnumerable source, Func selector) { if (source == null) @@ -298,6 +479,23 @@ public static long Sum(this IEnumerable source, FuncComputes the sum of the sequence of values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate a sum. + /// A transform function to apply to each element. + /// The sum of the projected values. + /// or is . + /// method returns zero if `source` contains no elements. + /// You can apply this method to a sequence of arbitrary values if you provide a function, `selector`, that projects the members of `source` into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet98"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static float Sum(this IEnumerable source, Func selector) { if (source == null) @@ -319,6 +517,24 @@ public static float Sum(this IEnumerable source, FuncComputes the sum of the sequence of nullable values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate a sum. + /// A transform function to apply to each element. + /// The sum of the projected values. + /// or is . + /// ` in C# or `Nullable(Of Single)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet98"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static float? Sum(this IEnumerable source, Func selector) { if (source == null) @@ -344,6 +560,21 @@ public static float Sum(this IEnumerable source, FuncComputes the sum of the sequence of values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate a sum. + /// A transform function to apply to each element. + /// The sum of the projected values. + /// or is . + /// + /// This method returns zero if contains no elements. + /// You can apply this method to a sequence of arbitrary values if you provide a function, , that projects the members of into a numeric type, specifically . + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet98"::: + /// Aggregate Clause (Visual Basic) public static double Sum(this IEnumerable source, Func selector) { if (source == null) @@ -365,6 +596,24 @@ public static double Sum(this IEnumerable source, FuncComputes the sum of the sequence of nullable values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate a sum. + /// A transform function to apply to each element. + /// The sum of the projected values. + /// or is . + /// ` in C# or `Nullable(Of Double)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet98"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static double? Sum(this IEnumerable source, Func selector) { if (source == null) @@ -390,6 +639,24 @@ public static double Sum(this IEnumerable source, FuncComputes the sum of the sequence of values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate a sum. + /// A transform function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// . + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet98"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static decimal Sum(this IEnumerable source, Func selector) { if (source == null) @@ -411,6 +678,25 @@ public static decimal Sum(this IEnumerable source, FuncComputes the sum of the sequence of nullable values that are obtained by invoking a transform function on each element of the input sequence. + /// The type of the elements of . + /// A sequence of values that are used to calculate a sum. + /// A transform function to apply to each element. + /// The sum of the projected values. + /// or is . + /// The sum is larger than . + /// ` in C# or `Nullable(Of Decimal)` in Visual Basic. + /// In Visual Basic query expression syntax, an `Aggregate Into Sum()` clause translates to an invocation of . + /// ## Examples + /// The following code example demonstrates how to use to sum the projected values of a sequence. + /// [!INCLUDE[sqo_diff_overload_example_func](~/includes/sqo-diff-overload-example-func-md.md)] + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet98"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet98"::: + /// ]]> + /// Aggregate Clause (Visual Basic) public static decimal? Sum(this IEnumerable source, Func selector) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Take.cs b/src/libraries/System.Linq/src/System/Linq/Take.cs index dbb859348a7cd4..d5471fadfbc2a1 100644 --- a/src/libraries/System.Linq/src/System/Linq/Take.cs +++ b/src/libraries/System.Linq/src/System/Linq/Take.cs @@ -8,6 +8,23 @@ namespace System.Linq { public static partial class Enumerable { + /// Returns a specified number of contiguous elements from the start of a sequence. + /// The type of the elements of . + /// The sequence to return elements from. + /// The number of elements to return. + /// An that contains the specified number of elements from the start of the input sequence. + /// is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// enumerates and yields elements until elements have been yielded or contains no more elements. If exceeds the number of elements in , all elements of are returned. + /// If is less than or equal to zero, is not enumerated and an empty is returned. + /// The and methods are functional complements. Given a sequence `coll` and an integer `n`, concatenating the results of `coll.Take(n)` and `coll.Skip(n)` yields the same sequence as `coll`. + /// In Visual Basic query expression syntax, a `Take` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to return elements from the start of a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet99"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet99"::: + /// Take Clause (Visual Basic) public static IEnumerable Take(this IEnumerable source, int count) { if (source == null) @@ -21,13 +38,15 @@ public static IEnumerable Take(this IEnumerable sourc } /// Returns a specified range of contiguous elements from a sequence. + /// The type of the elements of . /// The sequence to return elements from. /// The range of elements to return, which has start and end indexes either from the start or the end. - /// The type of the elements of . - /// - /// is . - /// + /// is . /// An that contains the specified of elements from the sequence. + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// enumerates and yields elements whose indices belong to the specified . + /// public static IEnumerable Take(this IEnumerable source, Range range) { if (source == null) @@ -180,6 +199,22 @@ static int CalculateEndIndex(bool isEndIndexFromEnd, int endIndex, int count) => Math.Min(count, isEndIndexFromEnd ? count - endIndex : endIndex); } + /// Returns elements from a sequence as long as a specified condition is true. + /// The type of the elements of . + /// A sequence to return elements from. + /// A function to test each element for a condition. + /// An that contains the elements from the input sequence that occur before the element at which the test no longer passes. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method tests each element of by using and yields the element if the result is . Enumeration stops when the predicate function returns for an element or when contains no more elements. + /// The and methods are functional complements. Given a sequence `coll` and a pure function `p`, concatenating the results of `coll.TakeWhile(p)` and `coll.SkipWhile(p)` yields the same sequence as `coll`. + /// In Visual Basic query expression syntax, a `Take While` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to return elements from the start of a sequence as long as a condition is true. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet100"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet100"::: + /// Take While Clause (Visual Basic) public static IEnumerable TakeWhile(this IEnumerable source, Func predicate) { if (source == null) @@ -208,6 +243,23 @@ private static IEnumerable TakeWhileIterator(IEnumerableReturns elements from a sequence as long as a specified condition is true. The element's index is used in the logic of the predicate function. + /// The type of the elements of . + /// The sequence to return elements from. + /// A function to test each source element for a condition; the second parameter of the function represents the index of the source element. + /// An that contains elements from the input sequence that occur before the element at which the test no longer passes. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method tests each element of by using and yields the element if the result is . Enumeration stops when the predicate function returns for an element or when contains no more elements. + /// The first argument of represents the element to test. The second argument represents the zero-based index of the element within . + /// The and methods are functional complements. Given a sequence `coll` and a pure function `p`, concatenating the results of `coll.TakeWhile(p)` and `coll.SkipWhile(p)` yields the same sequence as `coll`. + /// In Visual Basic query expression syntax, a `Take While` clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to return elements from the start of a sequence as long as a condition that uses the element's index is true. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet101"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet101"::: + /// Take While Clause (Visual Basic) public static IEnumerable TakeWhile(this IEnumerable source, Func predicate) { if (source == null) @@ -242,6 +294,13 @@ private static IEnumerable TakeWhileIterator(IEnumerableReturns a new enumerable collection that contains the last elements from . + /// The type of the elements in the enumerable collection. + /// An enumerable collection instance. + /// The number of elements to take from the end of the collection. + /// A new enumerable collection that contains the last elements from . + /// is . + /// If is not a positive number, this method returns an empty enumerable collection. public static IEnumerable TakeLast(this IEnumerable source, int count) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/ToCollection.cs b/src/libraries/System.Linq/src/System/Linq/ToCollection.cs index 038a47e93160c6..594b6fc8c5cdfe 100644 --- a/src/libraries/System.Linq/src/System/Linq/ToCollection.cs +++ b/src/libraries/System.Linq/src/System/Linq/ToCollection.cs @@ -7,6 +7,18 @@ namespace System.Linq { public static partial class Enumerable { + /// Creates an array from a . + /// The type of the elements of . + /// An to create an array from. + /// An array that contains the elements from the input sequence. + /// is . + /// + /// The method forces immediate query evaluation and returns an array that contains the query results. You can append this method to your query in order to obtain a cached copy of the query results. + /// has similar behavior but returns a instead of an array. + /// + /// The following code example demonstrates how to use to force immediate query evaluation and return an array of results. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet104"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet104"::: public static TSource[] ToArray(this IEnumerable source) { if (source == null) @@ -19,6 +31,18 @@ public static TSource[] ToArray(this IEnumerable source) : EnumerableHelpers.ToArray(source); } + /// Creates a from an . + /// The type of the elements of . + /// The to create a from. + /// A that contains elements from the input sequence. + /// is . + /// + /// The method forces immediate query evaluation and returns a that contains the query results. You can append this method to your query in order to obtain a cached copy of the query results. + /// has similar behavior but returns an array instead of a . + /// + /// The following code example demonstrates how to use to force immediate query evaluation and return a that contains the query results. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet106"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet106"::: public static List ToList(this IEnumerable source) { if (source == null) @@ -29,9 +53,35 @@ public static List ToList(this IEnumerable source) return source is IIListProvider listProvider ? listProvider.ToList() : new List(source); } + /// Creates a from an according to a specified key selector function. + /// The type of the elements of . + /// The type of the key returned by . + /// An to create a from. + /// A function to extract a key from each element. + /// A that contains keys and values. The values within each group are in the same order as in . + /// or is . + /// -or- + /// produces a key that is . + /// produces duplicate keys for two elements. + /// The method uses the default equality comparer to compare keys. + /// The following code example demonstrates how to use to create a by using a key selector. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" id="Snippet105"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet105"::: public static Dictionary ToDictionary(this IEnumerable source, Func keySelector) where TKey : notnull => ToDictionary(source, keySelector, null); + /// Creates a from an according to a specified key selector function and key comparer. + /// The type of the elements of . + /// The type of the keys returned by . + /// An to create a from. + /// A function to extract a key from each element. + /// An to compare keys. + /// A that contains keys and values. The values within each group are in the same order as in . + /// or is . + /// -or- + /// produces a key that is . + /// produces duplicate keys for two elements. + /// If is , the default equality comparer is used to compare keys. public static Dictionary ToDictionary(this IEnumerable source, Func keySelector, IEqualityComparer? comparer) where TKey : notnull { if (source == null) @@ -95,9 +145,36 @@ private static Dictionary ToDictionary(ListCreates a from an according to specified key selector and element selector functions. + /// The type of the elements of . + /// The type of the key returned by . + /// The type of the value returned by . + /// An to create a from. + /// A function to extract a key from each element. + /// A transform function to produce a result element value from each element. + /// A that contains values of type selected from the input sequence. + /// or or is . + /// -or- + /// produces a key that is . + /// produces duplicate keys for two elements. + /// The method uses the default equality comparer to compare keys. public static Dictionary ToDictionary(this IEnumerable source, Func keySelector, Func elementSelector) where TKey : notnull => ToDictionary(source, keySelector, elementSelector, null); + /// Creates a from an according to a specified key selector function, a comparer, and an element selector function. + /// The type of the elements of . + /// The type of the key returned by . + /// The type of the value returned by . + /// An to create a from. + /// A function to extract a key from each element. + /// A transform function to produce a result element value from each element. + /// An to compare keys. + /// A that contains values of type selected from the input sequence. + /// or or is . + /// -or- + /// produces a key that is . + /// produces duplicate keys for two elements. + /// If is , the default equality comparer is used to compare keys. public static Dictionary ToDictionary(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer? comparer) where TKey : notnull { if (source == null) @@ -166,8 +243,17 @@ private static Dictionary ToDictionary( return d; } + /// Creates a from an . + /// The type of the elements of . + /// An to create a from. + /// A that contains values of type selected from the input sequence. public static HashSet ToHashSet(this IEnumerable source) => source.ToHashSet(comparer: null); + /// Creates a from an using the to compare keys. + /// The type of the elements of . + /// An to create a from. + /// An to compare keys. + /// A that contains values of type selected from the input sequence. public static HashSet ToHashSet(this IEnumerable source, IEqualityComparer? comparer) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Union.cs b/src/libraries/System.Linq/src/System/Linq/Union.cs index bc7eb36843d721..3adfb6620a938d 100644 --- a/src/libraries/System.Linq/src/System/Linq/Union.cs +++ b/src/libraries/System.Linq/src/System/Linq/Union.cs @@ -9,8 +9,52 @@ namespace System.Linq { public static partial class Enumerable { + /// Produces the set union of two sequences by using the default equality comparer. + /// The type of the elements of the input sequences. + /// An whose distinct elements form the first set for the union. + /// An whose distinct elements form the second set for the union. + /// An that contains the elements from both input sequences, excluding duplicates. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// This method excludes duplicates from the return set. This is different behavior to the method, which returns all the elements in the input sequences including duplicates. + /// The default equality comparer, , is used to compare values of the types that implement the generic interface. To compare a custom data type, you need to implement this interface and provide your own and methods for the type. + /// When the object returned by this method is enumerated, `Union` enumerates and in that order and yields each element that has not already been yielded. + /// + /// The following code example demonstrates how to use to obtain the union of two sequences of integers. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet109"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet109"::: + /// If you want to compare sequences of objects of some custom data type, you have to implement the generic interface in a helper class. The following code example shows how to implement this interface in a custom data type and override and methods. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet9"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet9"::: + /// After you implement this interface, you can use sequences of `ProductA` objects in the method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet10"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet10"::: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/CS/EncapsulatedComparer.cs" id="Snippet4"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQEncapsulatedComparer/VB/EncapsulatedComparer.vb" id="Snippet4"::: public static IEnumerable Union(this IEnumerable first, IEnumerable second) => Union(first, second, comparer: null); + /// Produces the set union of two sequences by using a specified . + /// The type of the elements of the input sequences. + /// An whose distinct elements form the first set for the union. + /// An whose distinct elements form the second set for the union. + /// The to compare values. + /// An that contains the elements from both input sequences, excluding duplicates. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// If is , the default equality comparer, , is used to compare values. + /// When the object returned by this method is enumerated, enumerates and in that order and yields each element that has not already been yielded. + /// The method differs from the method because the method returns all the elements in the input sequences including duplicates, whereas returns only unique values. + /// + /// The following example shows how to implement an equality comparer that can be used in the method. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet1"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet1"::: + /// After you implement this comparer, you can use sequences of `Product` objects in the method, as shown in the following example: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet2"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet2"::: + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsLINQCustomComparer/CS/CustomComparer.cs" id="Snippet4"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_VBCSharp/CsLINQCustomComparer/VB/CustomComparer.vb" id="Snippet4"::: public static IEnumerable Union(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) { if (first == null) @@ -26,8 +70,35 @@ public static IEnumerable Union(this IEnumerable firs return first is UnionIterator union && AreEqualityComparersEqual(comparer, union._comparer) ? union.Union(second) : new UnionIterator2(first, second, comparer); } + /// Produces the set union of two sequences according to a specified key selector function. + /// The type of the elements of the input sequences. + /// The type of key to identify elements by. + /// An whose distinct elements form the first set for the union. + /// An whose distinct elements form the second set for the union. + /// A function to extract the key for each element. + /// An that contains the elements from both input sequences, excluding duplicates. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The default equality comparer, , is used to compare values. + /// When the object returned by this method is enumerated, enumerates and in that order and yields each element that has not already been yielded. + /// public static IEnumerable UnionBy(this IEnumerable first, IEnumerable second, Func keySelector) => UnionBy(first, second, keySelector, null); + /// Produces the set union of two sequences according to a specified key selector function. + /// The type of the elements of the input sequences. + /// The type of key to identify elements by. + /// An whose distinct elements form the first set for the union. + /// An whose distinct elements form the second set for the union. + /// A function to extract the key for each element. + /// The to compare values. + /// An that contains the elements from both input sequences, excluding duplicates. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// If is , the default equality comparer, , is used to compare values. + /// When the object returned by this method is enumerated, enumerates and in that order and yields each element that has not already been yielded. + /// public static IEnumerable UnionBy(this IEnumerable first, IEnumerable second, Func keySelector, IEqualityComparer? comparer) { if (first is null) diff --git a/src/libraries/System.Linq/src/System/Linq/Where.cs b/src/libraries/System.Linq/src/System/Linq/Where.cs index 6a19e5cb471dae..b4753b6675290a 100644 --- a/src/libraries/System.Linq/src/System/Linq/Where.cs +++ b/src/libraries/System.Linq/src/System/Linq/Where.cs @@ -9,6 +9,21 @@ namespace System.Linq { public static partial class Enumerable { + /// Filters a sequence of values based on a predicate. + /// The type of the elements of . + /// An to filter. + /// A function to test each element for a condition. + /// An that contains elements from the input sequence that satisfy the condition. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// In query expression syntax, a `where` (Visual C#) or `Where` (Visual Basic) clause translates to an invocation of . + /// + /// The following code example demonstrates how to use to filter a sequence. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet110"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet110"::: + /// where clause (C# Reference) + /// Where Clause (Visual Basic) public static IEnumerable Where(this IEnumerable source, Func predicate) { if (source == null) @@ -41,6 +56,19 @@ public static IEnumerable Where(this IEnumerable sour return new WhereEnumerableIterator(source, predicate); } + /// Filters a sequence of values based on a predicate. Each element's index is used in the logic of the predicate function. + /// The type of the elements of . + /// An to filter. + /// A function to test each source element for a condition; the second parameter of the function represents the index of the source element. + /// An that contains elements from the input sequence that satisfy the condition. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The first argument of represents the element to test. The second argument represents the zero-based index of the element within . + /// + /// The following code example demonstrates how to use to filter a sequence based on a predicate that involves the index of each element. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet111"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet111"::: public static IEnumerable Where(this IEnumerable source, Func predicate) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Zip.cs b/src/libraries/System.Linq/src/System/Linq/Zip.cs index d0a380086d2289..fca3da919e50db 100644 --- a/src/libraries/System.Linq/src/System/Linq/Zip.cs +++ b/src/libraries/System.Linq/src/System/Linq/Zip.cs @@ -5,8 +5,33 @@ namespace System.Linq { + /// Provides a set of ( in Visual Basic) methods for querying objects that implement . + /// + /// The methods in this class provide an implementation of the standard query operators for querying data sources that implement . The standard query operators are general purpose methods that follow the LINQ pattern and enable you to express traversal, filter, and projection operations over data in any .NET-based programming language. + /// The majority of the methods in this class are defined as extension methods that extend . This means they can be called like an instance method on any object that implements . + /// Methods that are used in a query that returns a sequence of values do not consume the target data until the query object is enumerated. This is known as deferred execution. Methods that are used in a query that returns a singleton value execute and consume the target data immediately. + /// + /// Standard Query Operators Overview + /// Extension Methods (C# Programming Guide) + /// Extension Methods (Visual Basic) public static partial class Enumerable { + /// Applies a specified function to the corresponding elements of two sequences, producing a sequence of the results. + /// The type of the elements of the first input sequence. + /// The type of the elements of the second input sequence. + /// The type of the elements of the result sequence. + /// The first sequence to merge. + /// The second sequence to merge. + /// A function that specifies how to merge the elements from the two sequences. + /// An that contains merged elements of two input sequences. + /// or is . + /// + /// This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its `GetEnumerator` method directly or by using `foreach` in Visual C# or `For Each` in Visual Basic. + /// The method merges each element of the first sequence with an element that has the same index in the second sequence. If the sequences do not have the same number of elements, the method merges sequences until it reaches the end of one of them. For example, if one sequence has three elements and the other one has four, the result sequence will have only three elements. + /// + /// The following code example demonstrates how to use the method to merge two sequences. + /// :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Linq.Enumerable/CS/enumerable.cs" interactive="try-dotnet-method" id="Snippet200"::: + /// :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Linq.Enumerable/VB/Enumerable.vb" id="Snippet200"::: public static IEnumerable Zip(this IEnumerable first, IEnumerable second, Func resultSelector) { if (first is null) @@ -27,6 +52,12 @@ public static IEnumerable Zip(this IEnumerabl return ZipIterator(first, second, resultSelector); } + /// Produces a sequence of tuples with elements from the two specified sequences. + /// The type of the elements of the first input sequence. + /// The type of the elements of the second input sequence. + /// The first sequence to merge. + /// The second sequence to merge. + /// A sequence of tuples with elements taken from the first and second sequences, in that order. public static IEnumerable<(TFirst First, TSecond Second)> Zip(this IEnumerable first, IEnumerable second) { if (first is null)