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.Collections.Generic; 6 using System.Collections.ObjectModel; 7 using System.Dynamic.Utils; 8 9 namespace System.Dynamic 10 { 11 /// <summary> 12 /// Describes arguments in the dynamic binding process. 13 /// </summary> 14 /// <remarks> 15 /// <see cref="ArgumentCount"/> - all inclusive number of arguments. 16 /// <see cref="ArgumentNames"/> - names for those arguments that are named. 17 /// 18 /// Argument names match to the argument values in left to right order 19 /// and last name corresponds to the last argument. 20 /// </remarks> 21 /// <example> 22 /// <code> 23 /// Foo(arg1, arg2, arg3, name1 = arg4, name2 = arg5, name3 = arg6) 24 /// </code> 25 /// will correspond to 26 /// <code> 27 /// new CallInfo(6, "name1", "name2", "name3") 28 /// </code> 29 /// </example> 30 public sealed class CallInfo 31 { 32 /// <summary> 33 /// Creates a new <see cref="CallInfo"/> that represents arguments in the dynamic binding process. 34 /// </summary> 35 /// <param name="argCount">The number of arguments.</param> 36 /// <param name="argNames">The argument names.</param> 37 /// <returns>The new <see cref="CallInfo"/> instance.</returns> CallInfo(int argCount, params string[] argNames)38 public CallInfo(int argCount, params string[] argNames) 39 : this(argCount, (IEnumerable<string>)argNames) 40 { 41 } 42 43 /// <summary> 44 /// Creates a new <see cref="CallInfo"/> that represents arguments in the dynamic binding process. 45 /// </summary> 46 /// <param name="argCount">The number of arguments.</param> 47 /// <param name="argNames">The argument names.</param> 48 /// <returns>The new <see cref="CallInfo"/> instance.</returns> CallInfo(int argCount, IEnumerable<string> argNames)49 public CallInfo(int argCount, IEnumerable<string> argNames) 50 { 51 ContractUtils.RequiresNotNull(argNames, nameof(argNames)); 52 53 var argNameCol = argNames.ToReadOnly(); 54 55 if (argCount < argNameCol.Count) throw System.Linq.Expressions.Error.ArgCntMustBeGreaterThanNameCnt(); 56 ContractUtils.RequiresNotNullItems(argNameCol, nameof(argNames)); 57 58 ArgumentCount = argCount; 59 ArgumentNames = argNameCol; 60 } 61 62 /// <summary> 63 /// The number of arguments. 64 /// </summary> 65 public int ArgumentCount { get; } 66 67 /// <summary> 68 /// The argument names. 69 /// </summary> 70 public ReadOnlyCollection<string> ArgumentNames { get; } 71 72 /// <summary> 73 /// Serves as a hash function for the current <see cref="CallInfo"/>. 74 /// </summary> 75 /// <returns>A hash code for the current <see cref="CallInfo"/>.</returns> GetHashCode()76 public override int GetHashCode() 77 { 78 return ArgumentCount ^ ArgumentNames.ListHashCode(); 79 } 80 81 /// <summary> 82 /// Determines whether the specified <see cref="CallInfo"/> instance is considered equal to the current instance. 83 /// </summary> 84 /// <param name="obj">The instance of <see cref="CallInfo"/> to compare with the current instance.</param> 85 /// <returns>true if the specified instance is equal to the current one otherwise, false.</returns> Equals(object obj)86 public override bool Equals(object obj) 87 { 88 var other = obj as CallInfo; 89 return other != null && ArgumentCount == other.ArgumentCount && ArgumentNames.ListEquals(other.ArgumentNames); 90 } 91 } 92 } 93