using System; using System.Linq; using System.Reflection; namespace RobloxFiles.Utility { // This is a lazy helper class to disambiguate between FieldInfo and PropertyInfo internal class ImplicitMember { private const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase; private readonly object member; private readonly string inputName; private ImplicitMember(FieldInfo field, string name) { member = field; inputName = name; } private ImplicitMember(PropertyInfo prop, string name) { member = prop; inputName = name; } public static ImplicitMember Get(Type type, string name) { var field = type .GetFields(flags) .Where(f => f.Name == name) .FirstOrDefault(); if (field != null) return new ImplicitMember(field, name); var prop = type .GetProperties(flags) .Where(p => p.Name == name) .FirstOrDefault(); if (prop != null) return new ImplicitMember(prop, name); return null; } public Type MemberType { get { switch (member) { case PropertyInfo prop: return prop.PropertyType; case FieldInfo field: return field.FieldType; default: return null; } } } public object GetValue(object obj) { object result = null; switch (member) { case FieldInfo field: { result = field.GetValue(obj); break; } case PropertyInfo prop: { result = prop.GetValue(obj); break; } } return result; } public void SetValue(object obj, object value) { switch (member) { case FieldInfo field: { field.SetValue(obj, value); return; } case PropertyInfo prop: { prop.SetValue(obj, value); return; } } RobloxFile.LogError($"Unknown field '{inputName}' in ImplicitMember.SetValue"); } } }