private void CheckPossibleValueInUnion(object value, ICustomAttributeProvider provider) { string switchExpr; if (provider == null || !MarshalingDescriptor.TryGetAttribute <string>( provider, typeof(SwitchAttribute), "expr", out switchExpr)) { throw new InvalidOperationException(String.Format( CultureInfo.InvariantCulture, "cannot find switch attribute for union '{0}'", value.GetType().Name)); } Type type = value.GetType(); var fieldsToCheck = new List <FieldInfo>(); var defaultFields = new List <FieldInfo>(); foreach (var field in type.GetFields()) { string caseExpr; if (MarshalingDescriptor.TryGetAttribute <string>(field, typeof(CaseAttribute), "expr", out caseExpr)) { IList <int?> caseValues = marshaler.EvaluateConstant(caseExpr); int switchValue = marshaler.Evaluate(switchExpr); if (caseValues.Contains(switchValue)) { fieldsToCheck.Add(field); } } else if (field.GetCustomAttributes(typeof(CaseDefaultAttribute), false).Length != 0) { defaultFields.Add(field); } } if (fieldsToCheck.Count == 0) { fieldsToCheck.AddRange(defaultFields); } foreach (var field in fieldsToCheck) { object fieldValue = field.GetValue(value); if (IsStruct(field.GetType())) { CheckPossibleValue(fieldValue, field); } else if (HasPossibleValue(field)) { CheckFieldValue(fieldValue, field); } } }