/// <summary> /// Filter the fields info to preserve only the fields that are marked by MarshalOrder, /// and sort the filtered fields. /// </summary> /// <param name="declaredFieldsInfo">Fields to be filtered and sorted.</param> /// <returns>Filtered and sorted fields info.</returns> protected static FieldInfo[] FilterAndSortFields(FieldInfo[] declaredFieldsInfo) { List <FieldInfo> fieldsList = declaredFieldsInfo.ToList(); List <int> toRemoveIndices = new List <int>(); for (int i = 0; i < fieldsList.Count; i++) { object[] fieldAttributes = fieldsList[i].GetCustomAttributes(typeof(MarshalOrderAttribute), true); if (fieldAttributes.Length != 1) { toRemoveIndices.Add(i); if (fieldAttributes.Length > 1) { // Prohibit the case where there are multiple MarshalOrder attributes. throw new InvalidMarshallableException(string.Format("MarshalOrder marked {0} times.", fieldAttributes.Length)); } continue; } } foreach (int index in toRemoveIndices.OrderByDescending(v => v)) { // Fields that have not been marked with MarshalOrder attribute // will not be marshalled from or unmarshalled to. fieldsList.RemoveAt(index); } declaredFieldsInfo = fieldsList.ToArray(); FieldComparer fieldComparer = new FieldComparer(); Array.Sort(declaredFieldsInfo, (x, y) => { return(fieldComparer.Compare(x, y)); }); // Make sure there are no duplicate attributes. int lastOrder = -1; for (int i = 0; i < declaredFieldsInfo.Length; i++) { MarshalOrderAttribute attribute = (MarshalOrderAttribute)declaredFieldsInfo[i] .GetCustomAttributes(typeof(MarshalOrderAttribute), true)[0]; if (i == 0) { lastOrder = attribute.Order; } else if (attribute.Order == lastOrder) { throw new InvalidMarshallableException(string.Format("Field {0} has a conflicting ID {1}.", declaredFieldsInfo[i].Name, lastOrder)); } } return(fieldsList.ToArray()); }
public int Compare(FieldInfo x, FieldInfo y) { object[] xAttributes = x.GetCustomAttributes(typeof(MarshalOrderAttribute), true); object[] yAttributes = y.GetCustomAttributes(typeof(MarshalOrderAttribute), true); if (xAttributes.Length < 1) { throw new ArgumentException( string.Format("The field {0} has {1} MarshalOrderAttribute.", x.Name, xAttributes.Length)); } if (yAttributes.Length < 1) { throw new ArgumentException( string.Format("The field {0} has {1} MarshalOrderAttribute.", y.Name, yAttributes.Length)); } MarshalOrderAttribute xAttribute = (MarshalOrderAttribute)xAttributes[0]; MarshalOrderAttribute yAttribute = (MarshalOrderAttribute)yAttributes[0]; return(xAttribute.Order.CompareTo(yAttribute.Order)); }