private ValueMember AddField(int fieldNumber, string memberName, Type itemType, Type defaultType, object defaultValue)
{
if (Type.IsArray)
{
throw new InvalidOperationException("Can't add fields to array type");
}
MemberInfo mi = null;
#if WINRT
mi = Helpers.IsEnum(Type) ? Type.GetTypeInfo().GetDeclaredField(memberName) : Helpers.GetInstanceMember(Type.GetTypeInfo(), memberName);
#else
MemberInfo[] members = Type.GetMember(memberName, Helpers.IsEnum(Type) ? BindingFlags.Static | BindingFlags.Public : BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (members != null && members.Length == 1)
{
mi = members[0];
}
#endif
if (mi == null)
{
throw new ArgumentException("Unable to determine member: " + memberName, nameof(memberName));
}
Type miType;
#if WINRT || PORTABLE
PropertyInfo pi = mi as PropertyInfo;
if (pi == null)
{
FieldInfo fi = mi as FieldInfo;
if (fi == null)
{
throw new NotSupportedException(mi.GetType().Name);
}
else
{
miType = fi.FieldType;
}
}
else
{
miType = pi.PropertyType;
}
#else
switch (mi.MemberType)
{
case MemberTypes.Field:
miType = ((FieldInfo)mi).FieldType; break;
case MemberTypes.Property:
miType = ((PropertyInfo)mi).PropertyType; break;
default:
throw new NotSupportedException(mi.MemberType.ToString());
}
#endif
// we can't check IgnoreListHandling (because of recursion when adding type) but we don't need to
// it will be checked in ValueSerializedBuilder.CompleteLevel stage
ResolveListTypes(_model, miType, ref itemType, ref defaultType);
var serializationSettings = new ValueSerializationSettings();
var memberSettings = new MemberMainSettingsValue {
Tag = fieldNumber
};
var level0 = serializationSettings.GetSettingsCopy(0).Basic;
level0.Collection.ConcreteType = defaultType;
level0.Collection.ItemType = itemType;
serializationSettings.SetSettings(level0, 0);
serializationSettings.DefaultValue = defaultValue;
var def = serializationSettings.DefaultLevel.GetValueOrDefault();
def.Basic = level0.MakeDefaultNestedLevel();
serializationSettings.DefaultLevel = def;
ValueMember newField = new ValueMember(memberSettings, serializationSettings, mi, Type, _model);
Add(newField);
return(newField);
}