public void Add(T result) { if (!_results.Contains(result)) { _results.Add(result); } }
private void MaxPriorityQueueConstructor(MaxPriorityQueue <int> pq) { Assert.True(pq.IsEmpty); var rand = new Random((int)DateTime.Now.Ticks & 0x0000ffff); var set = new TreeSet <int>(); var count = 0; while (count < 10000) { var next = rand.Next() % 100000; if (!set.Contains(next)) { pq.Push(next); set.Add(next); count++; Assert.Equal(set.Max, pq.Top); } } Assert.False(pq.IsEmpty); Assert.Equal(10000, pq.Count); for (var i = 0; i < 1000; i++) { Assert.Equal(set.Max, pq.Top); Assert.Equal(set.Max, pq.Pop()); set.RemoveMax(); } Assert.Equal(9000, pq.Count); var newCount = 0; while (newCount < 5000) { var next = rand.Next() % 100000; if (!set.Contains(next)) { pq.Push(next); set.Add(next); newCount++; } } Assert.Equal(14000, pq.Count); for (var i = 0; i < 4000; i++) { Assert.Equal(set.Max, pq.Top); Assert.Equal(set.Max, pq.Pop()); set.RemoveMax(); } Assert.Equal(10000, pq.Count); }
public void StoreTrigger(Trigger trigger, bool replaceExisting) { TriggerWrapper tw = new TriggerWrapper(trigger); lock (_triggerLock) { if (_triggersDictionary.Contains(tw.Name)) { if (!replaceExisting) { throw new NotSupportedException("Object already exists " + trigger.Name); } // don't delete orphaned job, this trigger has the job anyways RemoveTrigger(trigger.Name, false); } if (RetrieveJob(trigger.JobName) == null) { throw new ApplicationException("The job (" + trigger.JobName + ") referenced by the trigger does not exist."); } // add to triggers array _triggers.Add(tw); _triggersDictionary[tw.Name] = tw; lock (_pausedTriggers) { if (_pausedTriggers.Contains(trigger.Name) || _pausedJobs.Contains(trigger.JobName)) { tw.State = InternalTriggerState.Paused; if (_blockedJobs.Contains(trigger.JobName)) { tw.State = InternalTriggerState.PausedAndBlocked; } } else if (_blockedJobs.Contains(trigger.JobName)) { tw.State = InternalTriggerState.Blocked; } else { _timeTriggers.Add(tw); } } } }
public void TestICollectionTInterface() { ICollection <int> set = new TreeSet <int>(Enumerable.Range(0, 10)); Assert.False(set.IsReadOnly); Assert.Equal(10, set.Count); Assert.True(set.Contains(3)); set.Add(3); Assert.True(set.Contains(3)); Assert.Equal(10, set.Count); Assert.False(set.Contains(12)); set.Add(12); Assert.True(set.Contains(12)); Assert.Equal(11, set.Count); }
private static void TestBinaryTree() { structures.common.ISet <int> tree = new TreeSet <int>(); tree.Add(5); tree.Add(6); tree.Add(9); tree.Add(1); tree.Add(4); tree.Add(8); tree.Add(-15); tree.Remove(1); Console.Out.WriteLine(tree.Contains(1)); Console.Out.WriteLine(tree.Contains(9)); foreach (var elem in tree) { Console.Out.WriteLine(elem); } }
/// <summary> /// Determine whether the given time (in milliseconds) is 'included' by the /// Calendar. /// <p> /// Note that this Calendar is only has full-day precision. /// </p> /// </summary> public override bool IsTimeIncluded(DateTime timeStampUtc) { if (!base.IsTimeIncluded(timeStampUtc)) { return(false); } DateTime lookFor = timeStampUtc.Date; return(!(dates.Contains(lookFor))); }
/// <summary> /// Determine whether the given time (in milliseconds) is 'included' by the /// Calendar. /// <para> /// Note that this Calendar is only has full-day precision. /// </para> /// </summary> public override bool IsTimeIncluded(DateTimeOffset timeStampUtc) { if (!base.IsTimeIncluded(timeStampUtc)) { return(false); } //apply the timezone timeStampUtc = TimeZoneUtil.ConvertTime(timeStampUtc, this.TimeZone); DateTime lookFor = timeStampUtc.Date; return(!(dates.Contains(lookFor))); }
private void Enumerate(IPriorityQueue <int> pq) { var set = new TreeSet <int>(); Fill(pq, set, 5000); var count = 0; foreach (var item in pq) { count++; Assert.True(set.Contains(item)); } Assert.Equal(5000, count); for (var i = 0; i < 2500; i++) { Assert.True(set.Contains(pq.Pop())); } Assert.Equal(2500, pq.Count); count = 0; foreach (var item in pq) { count++; Assert.True(set.Contains(item)); } Assert.Equal(2500, count); Fill(pq, set, 1000); count = 0; foreach (var item in pq) { count++; Assert.True(set.Contains(item)); } Assert.Equal(3500, count); }
public void TestTreeSetSimpleOperations() { ISortedSet <int> set = new TreeSet <int>(); var count = 0; foreach (var item in set) { count++; } Assert.True(count == 0); Assert.True(set.Count == 0); set.Add(10); set.Add(20); set.Add(30); set.Add(5); set.Add(1); Assert.True(set.Contains(20)); Assert.False(set.Contains(100)); Assert.Equal(5, set.Count); Assert.Equal(30, set.Max); Assert.Equal(1, set.Min); var list = new List <int>(); foreach (var item in set) { list.Add(item); } Assert.True(list.Count == set.Count); foreach (var item in list) { Assert.True(set.Contains(item)); } var array = new int[5]; set.CopyTo(array, 0); foreach (var item in array) { Assert.True(set.Contains(item)); } Assert.True(set.Remove(5)); Assert.Equal(4, set.Count); Assert.False(set.Contains(5)); set.RemoveMin(); Assert.Equal(3, set.Count); Assert.False(set.Contains(1)); set.Clear(); Assert.Equal(0, set.Count); }
private void Fill(IPriorityQueue <int> pq, TreeSet <int> set, int count) { var rand = new Random((int)DateTime.Now.Ticks & 0x0000ffff); var index = 0; while (index < count) { var next = rand.Next(); if (!set.Contains(next)) { set.Add(next); pq.Push(next); index++; } } }
public void TestMaxPriortyQueueConstructor() { var pq1 = new MaxPriorityQueue <int>(); MaxPriorityQueueConstructor(pq1); var pq2 = new MaxPriorityQueue <Order>(new OrderComparer()); Assert.True(pq2.IsEmpty); MaxPriorityQueueConstructorWithOrder(pq2); Assert.False(pq2.IsEmpty); var pq3 = new MaxPriorityQueue <Order>((x1, x2) => x1.Id - x2.Id); Assert.True(pq3.IsEmpty); MaxPriorityQueueConstructorWithOrder(pq3); Assert.False(pq3.IsEmpty); var rand = new Random((int)DateTime.Now.Ticks & 0x0000ffff); var set = new TreeSet <int>(); var orderSet = new TreeSet <Order>(new OrderComparer()); var count = 0; while (count < 5000) { var next = rand.Next(); var order = new Order { Id = next }; if (!orderSet.Contains(order)) { set.Add(next); orderSet.Add(order); count++; } } var pq4 = new MaxPriorityQueue <Order>(orderSet, new OrderComparer().Compare); Assert.Equal(5000, pq4.Count); Push(pq4, set, rand, 1000); Assert.Equal(6000, pq4.Count); Pop(pq4, set, 2000); Assert.Equal(4000, pq4.Count); Push(pq4, set, rand, 10000); Assert.Equal(14000, pq4.Count); }
public void TestContains() { Random random = new Random(); TreeSet <int> set = new TreeSet <int>(branchingFactor: 4); for (int i = 0; i < 2 * 4 * 4; i++) { int value = random.Next(set.Count + 1); set.Add(i); // Use set.Contains(i) since this is a targeted collection API test #pragma warning disable xUnit2017 // Do not use Contains() to check if a value exists in a collection Assert.True(set.Contains(i)); #pragma warning restore xUnit2017 // Do not use Contains() to check if a value exists in a collection } set.Validate(ValidationRules.None); }
private void Push(MaxPriorityQueue <Order> pq, TreeSet <int> set, Random rand, int count) { var index = 0; while (index < count) { var next = rand.Next(); if (!set.Contains(next)) { var order = new Order { Id = next }; pq.Push(order); set.Add(next); index++; Assert.Equal(set.Max, pq.Top.Id); } } }
protected override void UpdateUserInterface() { CmdDelete.Enabled = DaysExcluded.SelectedIndex > -1; CmdAdd.Enabled = !mExcludedDates.Contains(ExcludeDay.Value.Date); foreach (var excDate in mCalendar.ExcludedDates) { mCalendar.RemoveExcludedDate(excDate); } foreach (var excDate in mExcludedDates) { mCalendar.AddExcludedDate(excDate); } mCalendar.Description = string.Format("Excluding {0} dates: ", mCalendar.ExcludedDates.Count); foreach (var excDate in mCalendar.ExcludedDates) { mCalendar.Description += excDate.Date.ToString(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern) + ", "; } mCalendar.Description = mCalendar.Description.TrimEnd(new[] { ',', ' ' }); }
public override int GetItemViewType(int position) { return(sectionHeaderTreeSet.Contains(position) ? TYPE_SEPARATOR : TYPE_ITEM); }
/// <summary> /// Initializes a new instance of the <see cref="Option"/> class. /// </summary> /// <param name="attribute">The attribute describing this option.</param> /// <param name="memberInfo">The <see cref="MemberInfo"/> object pointing to the member to which the attribute was applied.</param> /// <param name="cmdLineObject">The command line manager object.</param> /// <param name="optionGroups">A complete list of all available option groups.</param> /// <param name="numberFormatInfo">The number format info to use for parsing numerical arguments.</param> public Option(CommandLineOptionAttribute attribute, MemberInfo memberInfo, object cmdLineObject, ICollection <OptionGroup> optionGroups, NumberFormatInfo numberFormatInfo) { mObject = cmdLineObject; mMember = memberInfo; mUsage = attribute.BoolFunction; mDescription = attribute.Description; mNumberFormatInfo = numberFormatInfo ?? CultureInfo.CurrentCulture.NumberFormat; mDefaultValue = attribute.DefaultAssignmentValue; mMinValue = attribute.MinValue; mMaxValue = attribute.MaxValue; // Check the validity of the member for which this attribute was defined switch (memberInfo.MemberType) { case MemberTypes.Field: FieldInfo fieldInfo = (FieldInfo)memberInfo; if (fieldInfo.IsInitOnly || fieldInfo.IsLiteral) { throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal field for this attribute; field must be writeable"); } mOptionType = fieldInfo.FieldType; break; case MemberTypes.Method: MethodInfo method = (MethodInfo)memberInfo; ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length != 1) { throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal method for this attribute; the method must accept exactly one parameter"); } if (parameters[0].IsOut) { throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal method for this attribute; the parameter of the method must not be an out parameter"); } if (IsArray(parameters[0].ParameterType) || IsCollectionType(parameters[0].ParameterType)) { throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal method for this attribute; the parameter of the method must be a non-array and non-collection type"); } mOptionType = parameters[0].ParameterType; break; case MemberTypes.Property: PropertyInfo propInfo = (PropertyInfo)memberInfo; if (!propInfo.CanWrite && !IsCollectionType(propInfo.PropertyType)) { throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal property for this attribute; property for non-collection type must be writable"); } if (!propInfo.CanRead && IsCollectionType(propInfo.PropertyType)) { throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal property for this attribute; property for collection type must be readable"); } if (!(propInfo.CanRead && propInfo.CanWrite) && IsArray(propInfo.PropertyType)) { throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal property for this attribute; property representing array type must be both readable and writeable"); } mOptionType = propInfo.PropertyType; break; default: throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal member for this attribute; member must be a property, method (accepting one parameter) or a field"); } mMinOccurs = attribute.MinOccurs; // MaxOccurs does not have a default value (since this is different for various types), so we set it here. if (!attribute.IsMaxOccursSet) { // Use default setting for MaxOccurs if (IsArray(mOptionType) || IsCollectionType(mOptionType)) { mMaxOccurs = 0; // Unlimited } else { mMaxOccurs = 1; } } else { mMaxOccurs = attribute.MaxOccurs; } if (mMinOccurs > mMaxOccurs && mMaxOccurs > 0) { throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, String.Format(CultureInfo.CurrentUICulture, "MinOccurs ({0}) must not be larger than MaxOccurs ({1})", mMinOccurs, mMaxOccurs)); } if (mMaxOccurs != 1 && !(IsArray(mOptionType) || IsCollectionType(mOptionType)) && mMember.MemberType != MemberTypes.Method) { throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Invalid cardinality for member; MaxOccurs must be equal to one (1) for any non-array or non-collection type"); } CommandLineManagerAttribute objectAttr = (CommandLineManagerAttribute)Attribute.GetCustomAttribute(mObject.GetType(), typeof(CommandLineManagerAttribute)); if (objectAttr == null) { throw new AttributeException(String.Format(CultureInfo.CurrentUICulture, "Class {0} contains a CommandLineOptionAttribute, but does not have the attribute CommandLineObjectAttribute", mObject.GetType().FullName)); } // Assign the name of this option from the member itself if no name is explicitly provided if (attribute.Name == null) { mName = memberInfo.Name; } else { mName = attribute.Name; } // Find the group (if any) that this option belongs to in the list of available option groups if (attribute.GroupId != null) { if (!optionGroups.Find(new Func <OptionGroup, bool>( delegate(OptionGroup searchGroup) { return(attribute.GroupId.Equals(searchGroup.Id)); }), out mGroup)) { throw new LogicException(String.Format(CultureInfo.CurrentUICulture, "Undefined group {0} referenced from member {1} in {2}", attribute.GroupId, memberInfo.Name, cmdLineObject.GetType().FullName)); } mGroup.Options.Add(mName, this); } // Recursively find out if this option requires explicit assignment if (attribute.DoesRequireExplicitAssignment.HasValue) { mRequireExplicitAssignment = attribute.DoesRequireExplicitAssignment.Value; } else if (mGroup != null) { mRequireExplicitAssignment = mGroup.RequireExplicitAssignment; } else { mRequireExplicitAssignment = objectAttr.RequireExplicitAssignment; } // Make sure the type of the field, property or method is supported if (!IsTypeSupported(mOptionType)) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "Unsupported type for command line option."); } // Make sure MinValue and MaxValue is not specified for any non-numerical type. if (mMinValue != null || mMaxValue != null) { if (!IsNumericalType) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "MinValue and MaxValue must not be specified for a non-numerical type"); } else if (!mMinValue.GetType().IsAssignableFrom(GetBaseType(mOptionType))) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "Illegal value for MinValue or MaxValue, not the same type as option"); } } // Some special checks for numerical types if (IsNumericalType) { // Assign the default MinValue if it was not set and this is a numerical type if (IsNumericalType && mMinValue == null) { mMinValue = GetBaseType(mOptionType).GetField("MinValue", BindingFlags.Static | BindingFlags.Public).GetValue(null); } // Assign the defaul MaxValue if it was not set and this is a numerical type if (IsNumericalType && mMaxValue == null) { mMaxValue = GetBaseType(mOptionType).GetField("MaxValue", BindingFlags.Static | BindingFlags.Public).GetValue(null); } // Check that MinValue <= MaxValue if (IsNumericalType && ((IComparable)MinValue).CompareTo(MaxValue) > 0) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "MinValue must not be greater than MaxValue"); } } // Check that the DefaultValue is not set if the option does not require explicit assignment. // If it were allowed, it would be ambiguos for an option separated from a value by a white space character // since we wouldn't know whether that would set the default value or assign it to the following value. if (mDefaultValue != null && !mRequireExplicitAssignment) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "DefaultValue must not be specified when RequireExplicitAssignment is set to false"); } // Check that the type of any set default value matches that of this option, or is string, and // convert it to the type of this option. if (mDefaultValue != null) { if (mDefaultValue.GetType() == typeof(string)) { try { mDefaultValue = GetCheckedValueForSetOperation(mDefaultValue); } catch (OverflowException) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "DefaultValue was less than MinValue or greater than MaxValue for this option"); } catch (FormatException) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "DefaultValue was not specified in the correct format for the type of this option"); } } else if (GetBaseType(mOptionType) != mDefaultValue.GetType()) { try { mDefaultValue = Convert.ChangeType(mDefaultValue, GetBaseType(mOptionType), mNumberFormatInfo); } catch (InvalidCastException) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "The type of the DefaultValue specified is not compatible with the type of the member to which this attribute applies"); } } } // If this is an enum, check that it doesn't have members only distinguishable by case, and // add the members to the mEnumerationValues set for speedy access when checking values assigned // to this member. Type type = GetBaseType(mOptionType); if (type.IsEnum) { mEnumerationValues = new TreeSet <string>(StringComparer.OrdinalIgnoreCase); foreach (FieldInfo field in type.GetFields()) { if (field.IsLiteral) { if (mEnumerationValues.Contains(field.Name)) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "This enumeration is not allowed as a command line option since it contains fields that differ only by case"); } mEnumerationValues.Add(field.Name); } } } }
public void TestTreeSetRandomOperations() { for (int j = 0; j < 10; j++) { ISortedSet <int> set = new TreeSet <int>(); Random randomValue = new Random((int)(DateTime.Now.Ticks & 0x0000FFFF)); List <int> list = new List <int>(); int testNumber = 1000; while (set.Count < testNumber) { int v = randomValue.Next(); if (!set.Contains(v)) { set.Add(v); list.Add(v); } } int count = 0; foreach (var item in set) { Assert.True(list.Contains(item)); count++; } Assert.True(count == set.Count); Assert.Equal(testNumber, set.Count); Random randomIndex = new Random((int)(DateTime.Now.Ticks & 0x0000FFFF)); for (int i = 0; i < 100; i++) { int index = randomIndex.Next(); index = index < 0 ? (-index) : index; index %= testNumber; int testValue = list[index]; Assert.True(set.Contains(testValue)); } for (int i = 0; i < 100; i++) { int min = list.Min(); Assert.Equal(min, set.Min); set.RemoveMin(); Assert.Equal(testNumber - i - 1, set.Count); Assert.False(set.Contains(min)); list.Remove(min); } testNumber -= 100; for (int i = 0; i < 100; i++) { int max = list.Max(); Assert.Equal(max, set.Max); set.RemoveMax(); Assert.Equal(testNumber - i - 1, set.Count); Assert.False(set.Contains(max)); list.Remove(max); } testNumber -= 100; for (int i = 0; i < 100; i++) { int index = randomIndex.Next(); index = index < 0 ? (-index) : index; index %= testNumber - i; int toRemove = list[index]; Assert.True(set.Contains(toRemove)); Assert.True(set.Remove(toRemove)); Assert.False(set.Contains(toRemove)); Assert.Equal(testNumber - i - 1, set.Count); list.Remove(toRemove); } } }
/// <summary> /// Initializes a new instance of the <see cref="Option"/> class. /// </summary> /// <param name="attribute">The attribute describing this option.</param> /// <param name="memberInfo">The <see cref="MemberInfo"/> object pointing to the member to which the attribute was applied.</param> /// <param name="cmdLineObject">The command line manager object.</param> /// <param name="optionGroups">A complete list of all available option groups.</param> /// <param name="numberFormatInfo">The number format info to use for parsing numerical arguments.</param> public Option(CommandLineOptionAttribute attribute, MemberInfo memberInfo, object cmdLineObject, ICollection<OptionGroup> optionGroups, NumberFormatInfo numberFormatInfo) { mObject = cmdLineObject; mMember = memberInfo; mUsage = attribute.BoolFunction; mDescription = attribute.Description; mNumberFormatInfo = numberFormatInfo ?? CultureInfo.CurrentCulture.NumberFormat; mDefaultValue = attribute.DefaultAssignmentValue; mMinValue = attribute.MinValue; mMaxValue = attribute.MaxValue; // Check the validity of the member for which this attribute was defined switch (memberInfo.MemberType) { case MemberTypes.Field: FieldInfo fieldInfo = (FieldInfo)memberInfo; if (fieldInfo.IsInitOnly || fieldInfo.IsLiteral) throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal field for this attribute; field must be writeable"); mOptionType = fieldInfo.FieldType; break; case MemberTypes.Method: MethodInfo method = (MethodInfo)memberInfo; ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length != 1) throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal method for this attribute; the method must accept exactly one parameter"); if (parameters[0].IsOut) throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal method for this attribute; the parameter of the method must not be an out parameter"); if (IsArray(parameters[0].ParameterType) || IsCollectionType(parameters[0].ParameterType)) throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal method for this attribute; the parameter of the method must be a non-array and non-collection type"); mOptionType = parameters[0].ParameterType; break; case MemberTypes.Property: PropertyInfo propInfo = (PropertyInfo)memberInfo; if (!propInfo.CanWrite && !IsCollectionType(propInfo.PropertyType)) throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal property for this attribute; property for non-collection type must be writable"); if (!propInfo.CanRead && IsCollectionType(propInfo.PropertyType)) throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal property for this attribute; property for collection type must be readable"); if (!(propInfo.CanRead && propInfo.CanWrite) && IsArray(propInfo.PropertyType)) throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal property for this attribute; property representing array type must be both readable and writeable"); mOptionType = propInfo.PropertyType; break; default: throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Illegal member for this attribute; member must be a property, method (accepting one parameter) or a field"); } mMinOccurs = attribute.MinOccurs; // MaxOccurs does not have a default value (since this is different for various types), so we set it here. if (!attribute.IsMaxOccursSet) { // Use default setting for MaxOccurs if (IsArray(mOptionType) || IsCollectionType(mOptionType)) mMaxOccurs = 0; // Unlimited else mMaxOccurs = 1; } else { mMaxOccurs = attribute.MaxOccurs; } if (mMinOccurs > mMaxOccurs && mMaxOccurs > 0) throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, String.Format(CultureInfo.CurrentUICulture, "MinOccurs ({0}) must not be larger than MaxOccurs ({1})", mMinOccurs, mMaxOccurs)); if (mMaxOccurs != 1 && !(IsArray(mOptionType) || IsCollectionType(mOptionType)) && mMember.MemberType != MemberTypes.Method) throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, "Invalid cardinality for member; MaxOccurs must be equal to one (1) for any non-array or non-collection type"); CommandLineManagerAttribute objectAttr = (CommandLineManagerAttribute)Attribute.GetCustomAttribute(mObject.GetType(), typeof(CommandLineManagerAttribute)); if (objectAttr == null) throw new AttributeException(String.Format(CultureInfo.CurrentUICulture, "Class {0} contains a CommandLineOptionAttribute, but does not have the attribute CommandLineObjectAttribute", mObject.GetType().FullName)); // Assign the name of this option from the member itself if no name is explicitly provided if (attribute.Name == null) { mName = memberInfo.Name; } else { mName = attribute.Name; } // Find the group (if any) that this option belongs to in the list of available option groups if (attribute.GroupId != null) { if (!optionGroups.Find(new Fun<OptionGroup, bool>( delegate(OptionGroup searchGroup) { return attribute.GroupId.Equals(searchGroup.Id); }), out mGroup)) { throw new LogicException(String.Format(CultureInfo.CurrentUICulture, "Undefined group {0} referenced from member {1} in {2}", attribute.GroupId, memberInfo.Name, cmdLineObject.GetType().FullName)); } mGroup.Options.Add(mName, this); } // Recursively find out if this option requires explicit assignment if (attribute.DoesRequireExplicitAssignment.HasValue) { mRequireExplicitAssignment = attribute.DoesRequireExplicitAssignment.Value; } else if (mGroup != null) { mRequireExplicitAssignment = mGroup.RequireExplicitAssignment; } else { mRequireExplicitAssignment = objectAttr.RequireExplicitAssignment; } // Make sure the type of the field, property or method is supported if (!IsTypeSupported(mOptionType)) throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "Unsupported type for command line option."); // Make sure MinValue and MaxValue is not specified for any non-numerical type. if (mMinValue != null || mMaxValue != null) { if (!IsNumericalType) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "MinValue and MaxValue must not be specified for a non-numerical type"); } else if (!mMinValue.GetType().IsAssignableFrom(GetBaseType(mOptionType))) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "Illegal value for MinValue or MaxValue, not the same type as option"); } } // Some special checks for numerical types if (IsNumericalType) { // Assign the default MinValue if it was not set and this is a numerical type if (IsNumericalType && mMinValue == null) { mMinValue = GetBaseType(mOptionType).GetField("MinValue", BindingFlags.Static | BindingFlags.Public).GetValue(null); } // Assign the defaul MaxValue if it was not set and this is a numerical type if (IsNumericalType && mMaxValue == null) { mMaxValue = GetBaseType(mOptionType).GetField("MaxValue", BindingFlags.Static | BindingFlags.Public).GetValue(null); } // Check that MinValue <= MaxValue if (IsNumericalType && ((IComparable)MinValue).CompareTo(MaxValue) > 0) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "MinValue must not be greater than MaxValue"); } } // Check that the DefaultValue is not set if the option does not require explicit assignment. // If it were allowed, it would be ambiguos for an option separated from a value by a white space character // since we wouldn't know whether that would set the default value or assign it to the following value. if (mDefaultValue != null && !mRequireExplicitAssignment) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "DefaultValue must not be specified when RequireExplicitAssignment is set to false"); } // Check that the type of any set default value matches that of this option, or is string, and // convert it to the type of this option. if (mDefaultValue != null) { if (mDefaultValue.GetType() == typeof(string)) { try { mDefaultValue = GetCheckedValueForSetOperation(mDefaultValue); } catch (OverflowException) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "DefaultValue was less than MinValue or greater than MaxValue for this option"); } catch (FormatException) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "DefaultValue was not specified in the correct format for the type of this option"); } } else if (GetBaseType(mOptionType) != mDefaultValue.GetType()) { try { mDefaultValue = Convert.ChangeType(mDefaultValue, GetBaseType(mOptionType), mNumberFormatInfo); } catch (InvalidCastException) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "The type of the DefaultValue specified is not compatible with the type of the member to which this attribute applies"); } } } // If this is an enum, check that it doesn't have members only distinguishable by case, and // add the members to the mEnumerationValues set for speedy access when checking values assigned // to this member. Type type = GetBaseType(mOptionType); if (type.IsEnum) { mEnumerationValues = new TreeSet<string>(StringComparer.OrdinalIgnoreCase); foreach (FieldInfo field in type.GetFields()) { if (field.IsLiteral) { if (mEnumerationValues.Contains(field.Name)) { throw new AttributeException(typeof(CommandLineOptionAttribute), mMember, "This enumeration is not allowed as a command line option since it contains fields that differ only by case"); } mEnumerationValues.Add(field.Name); } } } }