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 get member operation at the call site, providing the binding semantic and the details about the operation.
11     /// </summary>
12     public abstract class GetMemberBinder : DynamicMetaObjectBinder
13     {
14         /// <summary>
15         /// Initializes a new instance of the <see cref="GetMemberBinder" />.
16         /// </summary>
17         /// <param name="name">The name of the member to get.</param>
18         /// <param name="ignoreCase">true if the name should be matched ignoring case; false otherwise.</param>
GetMemberBinder(string name, bool ignoreCase)19         protected GetMemberBinder(string name, bool ignoreCase)
20         {
21             ContractUtils.RequiresNotNull(name, nameof(name));
22 
23             Name = name;
24             IgnoreCase = ignoreCase;
25         }
26 
27         /// <summary>
28         /// The result type of the operation.
29         /// </summary>
30         public override sealed Type ReturnType => typeof(object);
31 
32         /// <summary>
33         /// Gets the name of the member to get.
34         /// </summary>
35         public string Name { get; }
36 
37         /// <summary>
38         /// Gets the value indicating if the string comparison should ignore the case of the member name.
39         /// </summary>
40         public bool IgnoreCase { get; }
41 
42         /// <summary>
43         /// Performs the binding of the dynamic get member operation if the target dynamic object cannot bind.
44         /// </summary>
45         /// <param name="target">The target of the dynamic get member operation.</param>
46         /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
FallbackGetMember(DynamicMetaObject target)47         public DynamicMetaObject FallbackGetMember(DynamicMetaObject target)
48         {
49             return FallbackGetMember(target, null);
50         }
51 
52         /// <summary>
53         /// When overridden in the derived class, performs the binding of the dynamic get member operation if the target dynamic object cannot bind.
54         /// </summary>
55         /// <param name="target">The target of the dynamic get member operation.</param>
56         /// <param name="errorSuggestion">The binding result to use if binding fails, or null.</param>
57         /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)58         public abstract DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion);
59 
60         /// <summary>
61         /// Performs the binding of the dynamic get member operation.
62         /// </summary>
63         /// <param name="target">The target of the dynamic get member operation.</param>
64         /// <param name="args">An array of arguments of the dynamic get member operation.</param>
65         /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
Bind(DynamicMetaObject target, params DynamicMetaObject[] args)66         public sealed override DynamicMetaObject Bind(DynamicMetaObject target, params DynamicMetaObject[] args)
67         {
68             ContractUtils.RequiresNotNull(target, nameof(target));
69             ContractUtils.Requires(args == null || args.Length == 0, nameof(args));
70 
71             return target.BindGetMember(this);
72         }
73 
74         /// <summary>
75         /// Always returns <c>true</c> because this is a standard <see cref="DynamicMetaObjectBinder"/>.
76         /// </summary>
77         internal override sealed bool IsStandardBinder => true;
78     }
79 }
80