1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Dynamic.Utils;
6 
7 namespace System.Dynamic
8 {
9     /// <summary>
10     /// Represents the dynamic set index operation at the call site, providing the binding semantic and the details about the operation.
11     /// </summary>
12     public abstract class SetIndexBinder : DynamicMetaObjectBinder
13     {
14         /// <summary>
15         /// Initializes a new instance of the <see cref="SetIndexBinder" />.
16         /// </summary>
17         /// <param name="callInfo">The signature of the arguments at the call site.</param>
SetIndexBinder(CallInfo callInfo)18         protected SetIndexBinder(CallInfo callInfo)
19         {
20             ContractUtils.RequiresNotNull(callInfo, nameof(callInfo));
21             CallInfo = callInfo;
22         }
23 
24         /// <summary>
25         /// The result type of the operation.
26         /// </summary>
27         public override sealed Type ReturnType => typeof(object);
28 
29         /// <summary>
30         /// Gets the signature of the arguments at the call site.
31         /// </summary>
32         public CallInfo CallInfo { get; }
33 
34         /// <summary>
35         /// Performs the binding of the dynamic set index operation.
36         /// </summary>
37         /// <param name="target">The target of the dynamic set index operation.</param>
38         /// <param name="args">An array of arguments of the dynamic set index operation.</param>
39         /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
Bind(DynamicMetaObject target, DynamicMetaObject[] args)40         public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
41         {
42             ContractUtils.RequiresNotNull(target, nameof(target));
43             ContractUtils.RequiresNotNull(args, nameof(args));
44             ContractUtils.Requires(args.Length >= 2, nameof(args));
45 
46             DynamicMetaObject value = args[args.Length - 1];
47             DynamicMetaObject[] indexes = args.RemoveLast();
48 
49             ContractUtils.RequiresNotNull(value, nameof(args));
50             ContractUtils.RequiresNotNullItems(indexes, nameof(args));
51 
52             return target.BindSetIndex(this, indexes, value);
53         }
54 
55         /// <summary>
56         /// Always returns <c>true</c> because this is a standard <see cref="DynamicMetaObjectBinder"/>.
57         /// </summary>
58         internal override sealed bool IsStandardBinder => true;
59 
60         /// <summary>
61         /// Performs the binding of the dynamic set index operation if the target dynamic object cannot bind.
62         /// </summary>
63         /// <param name="target">The target of the dynamic set index operation.</param>
64         /// <param name="indexes">The arguments of the dynamic set index operation.</param>
65         /// <param name="value">The value to set to the collection.</param>
66         /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value)67         public DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value)
68         {
69             return FallbackSetIndex(target, indexes, value, null);
70         }
71 
72         /// <summary>
73         /// When overridden in the derived class, performs the binding of the dynamic set index operation if the target dynamic object cannot bind.
74         /// </summary>
75         /// <param name="target">The target of the dynamic set index operation.</param>
76         /// <param name="indexes">The arguments of the dynamic set index operation.</param>
77         /// <param name="value">The value to set to the collection.</param>
78         /// <param name="errorSuggestion">The binding result to use if binding fails, or null.</param>
79         /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion)80         public abstract DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion);
81     }
82 }
83