public _MemberAccessingFailure( Schema.Field field, _MemberAccessor ma, string nextMemberName, string cause) { this.field = field; this.memberAccessor = ma; this.nextMemberName = nextMemberName; this.cause = cause; }
private string _GetMemberValue( _MemberAccessor ma, object obj, out object value) { var pi = ma.info as PropertyInfo; var fi = ma.info as FieldInfo; value = (pi != null) ? pi.GetValue(obj, null) : fi.GetValue(obj); if (value == null) { if (!ma.canWrite) { return("Member is null but is not writable."); } if (ma.valueConstructor == null) { return("Default constructor not found."); } value = ma.valueConstructor.Invoke(null); if (pi != null) { pi.SetValue(obj, value, null); } else { fi.SetValue(obj, value); } } if (ma.arrayIndex < 0) { return(null); } var list = value; value = null; var count = _FillList(ma, list); if (count == 0) { return("List is 'ReadOnly' or 'FixedSize' but empty."); } if (ma.arrayIndex >= count) { return("Index is out of range. (IList<>.Count: " + count + ")"); } value = ma.listItemGetter .Invoke(list, new object[] { ma.arrayIndex }); if (value == null) { if (ma.listItemConstructor != null) { return("Member must be writable 'IList<>'."); } return("List item default constructor not found."); } return(null); }
private int _FillList(_MemberAccessor ma, object list) { var isArray = list.GetType().IsArray; var isReadOnly = (bool)ma.listReadOnlyGetter.Invoke(list, null); var count = (int)ma.listItemCountGetter.Invoke(list, null); if (!isArray && isReadOnly) { return(count); } if (ma.listItemConstructor != null) { for (var n = 0; n < count; ++n) { var item = ma.listItemGetter .Invoke(list, new object[] { n }); if (item != null) { continue; } item = ma.listItemConstructor.Invoke(null); ma.listItemSetter.Invoke(list, new object[] { item }); } } if (isArray) { return(count); } if (ma.listItemConstructor != null) { while (count <= ma.arrayIndex) { var item = ma.listItemConstructor.Invoke(null); ma.listItemAdder.Invoke(list, new object[] { item }); count = (int)ma.listItemCountGetter.Invoke(list, null); } } else { while (count <= ma.arrayIndex) { var item = default(object); if (ma.listItemType.IsValueType) { item = System.Activator.CreateInstance(ma.listItemType); } ma.listItemAdder.Invoke(list, new object[] { item }); count = (int)ma.listItemCountGetter.Invoke(list, null); } } return(count); }
private string _SetMemberValue( _MemberAccessor ma, object obj, object value) { var pi = ma.info as PropertyInfo; var fi = ma.info as FieldInfo; if (ma.arrayIndex < 0) { if (pi != null) { pi.SetValue(obj, value, null); } else { fi.SetValue(obj, value); } return(null); } var list = (pi != null) ? pi.GetValue(obj, null) : fi.GetValue(obj); if (list == null) { if (ma.valueConstructor == null) { return("Default constructor not found."); } list = ma.valueConstructor.Invoke(null); } var isReadOnly = (bool)ma.listReadOnlyGetter.Invoke(list, null); if (isReadOnly && !list.GetType().IsArray) { return("Member must be writable 'IList<>'."); } var count = _FillList(ma, list); if (ma.arrayIndex >= count) { return("Index is out of range. (IList<>.Count: " + count + ")"); } ma.listItemSetter .Invoke(list, new object[] { ma.arrayIndex, value }); return(null); }
private string _GetFullWarning( string message, _MemberAccessor ma = null, int rowIndex = -1) { var table = (DataTable)tableRef.Target; var name = table.name + "=>" + typeof(T).FullName; if (ma == null) { return(string.Format("{0}: {1}", name, message)); } else if (rowIndex < 0) { return(string.Format("{0}({2}=>{3}): {1}", name, message, ma.sourcePath, ma.targetPath )); } return(string.Format("{0}({4}, {2}=>{3}): {1}", name, message, ma.sourcePath, ma.targetPath, rowIndex )); }
private void _InitMemberAccessors() { var propMap = _CreatePropertyMap(); var accessors = new List <_MemberAccessor>(); var failures = new List <_MemberAccessingFailure>(); var fields = ((DataTable)tableRef.Target).schema.fieldsForWriter; var d = 0; var n = -1; var declarerStart = 0; var lastAccessorCount = 0; System.Func <string> getSourcePath = () => { var dotCount = 0; for (var m = 0; m < fields[n].name.Length; ++m) { if (fields[n].name[m] == '.') { if (++dotCount > d) { return(fields[n].name.Substring(0, m)); } } } return(fields[n].name); }; System.Func <string, string> getTargetName = (sourcePath) => { var sb = new StringBuilder(); foreach (var token in sourcePath.Split('.', '[')) { if (!char.IsNumber(token[0])) { sb.Append(token + "."); } } if (sb.Length > 0) { sb.Remove(sb.Length - 1, 1); } string v = null; if (propMap.TryGetValue(sb.ToString(), out v)) { return(v); } return(fields[n].nameNodes[d].name); }; System.Func <string, int> getDeclarerIndex = (sourcePath) => { for (var m = declarerStart; m < lastAccessorCount; ++m) { if (sourcePath.StartsWith(accessors[m].sourcePath)) { return(m); } } return(-1); }; System.Func <int, System.Type> getMemberValueType = (declarerIndex) => { if (declarerIndex < 0) { return(typeof(T)); } var ma = accessors[declarerIndex]; return((ma.arrayIndex < 0) ? ma.valueType : ma.listItemType); }; System.Func <MemberInfo, string> verifyMemberInfo = (mi) => { if (mi == null) { return("target '{0}' not found."); } else if (!_IsReadableMember(mi)) { return("target '{0}' is not readable."); } else if (_IsIndexedMember(mi)) { return("target '{0}' is indexer."); } var ai = fields[n].nameNodes[d].arrayIndex; var vt = _GetMemberValueType(mi); var lit = _GetListItemType(vt); vt = (ai < 0) ? vt : lit; if (ai >= 0 && lit == typeof(_NonListItem)) { return("target '{0}' is not 'IList<>' implementation."); } if (ai < 0 && !_IsWritableMember(mi)) { if (d == fields[n].depth) { return("target '{0}' must be writable."); } else if (vt.IsValueType) { return("" + "If target '{0}' is 'ValueType', " + "must be writable."); } } if (d < fields[n].depth) { return(null); } if (!vt.IsValueType && vt != typeof(string)) { return("target '{0}' is not 'ValueType' or 'string'."); } return(null); }; System.Func <int, string, string> getTargetPath = (declarerIndex, targetName) => { var sb = new StringBuilder(); if (declarerIndex >= 0) { sb.Append(accessors[declarerIndex].targetPath + "."); } var nd = fields[n].nameNodes[d]; sb.Append(targetName); if (nd.isArrayElement) { sb.Append("[" + nd.arrayIndex + "]"); } return(sb.ToString()); }; string lastSourcePath = null; while (true) { if (++n >= fields.Count) { ++d; n = -1; if (lastAccessorCount == accessors.Count) { break; } else { declarerStart = lastAccessorCount; lastAccessorCount = accessors.Count; continue; } } if (d > fields[n].depth) { continue; } var ai = fields[n].nameNodes[d].arrayIndex; var sp = getSourcePath(); if (sp == lastSourcePath) { continue; } lastSourcePath = sp; var tn = getTargetName(sp); var di = getDeclarerIndex(sp); if (di < 0 && d > 0) { continue; } var ma = (di < 0) ? null : accessors[di]; var mvt = getMemberValueType(di); var mi = _GetMemberInfo(mvt, tn); var err = verifyMemberInfo(mi); if (!string.IsNullOrEmpty(err)) { err = string.Format(err, tn); failures.Add( new _MemberAccessingFailure(fields[n], ma, tn, err) ); continue; } var tp = getTargetPath(di, tn); var mfi = (d < fields[n].depth) ? -1 : fields[n].index; ma = new _MemberAccessor(mi, ai, sp, tp, di, mfi); accessors.Add(ma); } _memberAccessors = accessors; _memberAccessingFailures = failures; }