protected virtual object Visit(Sequence sequence) { Type targetType = this._targetType.Peek(); object ret; if (targetType.IsArray) { Type elementType = targetType.GetElementType(); Array newArray = Array.CreateInstance(elementType, sequence.Elements.Length); this._targetType.Push(elementType); for (int elemNum = 0; elemNum < sequence.Elements.Length; elemNum++) { AstNode element = sequence.Elements[elemNum]; ValueError[] elementErrors = null; using (ErrorCollector errors = new ErrorCollector(this)) { object value = element.Visit(this); if (errors.Count == 0) newArray.SetValue(value, elemNum); elementErrors = errors.ToArray(); } this.RaiseError(elementErrors); } this._targetType.Pop(); ret = newArray; } else { Type realType; if (targetType.IsInterface) realType = OnResolveInterfaceType(targetType); else realType = targetType; ret = Activator.CreateInstance(realType); MethodInfo[] addMethods = realType.GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(a => StringComparer.InvariantCultureIgnoreCase.Equals(a.Name, "Add")) .ToArray(); for (int elemNum = 0; elemNum < sequence.Elements.Length; elemNum++) { List<ValueError> elementErrors = new List<ValueError>(); bool success = false; for (int addNum = 0; addNum < addMethods.Length; addNum++) { ParameterInfo[] addParams = addMethods[addNum].GetParameters(); if (addParams.Length != 1) continue; this._targetType.Push(addParams[0].ParameterType); using (ErrorCollector errors = new ErrorCollector(this)) { object value = sequence.Elements[elemNum].Visit(this); if (errors.Count == 0) { try { addMethods[addNum].Invoke(ret, new[] {value}); success = true; break; } catch (Exception ex) { this.RaiseError(new AddError(addMethods[addNum], new[] {value}, new[] {sequence.Elements[elemNum]}, ex)); } } elementErrors.AddRange(errors); } this._targetType.Pop(); } if (!success) { this.RaiseError(elementErrors); } } } return ret; }