/// <summary> /// Constructor. /// </summary> /// <param name="field"><see cref="System.Reflection.FieldInfo"/> to wrap.</param> internal ImmediateField([NotNull] FieldInfo field) : base(field) { FieldInfo = field; FieldType = field.FieldType; #if SUPPORTS_LAZY _fieldImmediateType = new Lazy <ImmediateType>(() => TypeAccessor.Get(FieldType)); #endif // ReSharper disable once AssignNullToNotNullAttribute, Justification: A field is always declared inside a type. DeclaringType = field.DeclaringType; // ReSharper disable once PossibleNullReferenceException, Justification: Declaring type for a field is always considered not null. // Current enum value field is not static compared to other enumeration available values fields // => That's why we need the static check if (field.IsStatic && DeclaringType.IsEnum) { // Getter / No setter object enumValue = field.GetValue(null); _getter = target => enumValue; _setter = (target, value) => throw new FieldAccessException("Cannot set an enumeration value."); } else { // Getter / Setter _getter = ConfigureGetter(); _setter = ConfigureSetter(); } #region Local functions bool IsConstantField() { return(field.IsLiteral || field.IsInitOnly); } GetterDelegate ConfigureGetter() { if (IsConstantField() && field.IsStatic) { object fieldValue = field.GetValue(null); return(target => fieldValue); } return(DelegatesFactory.CreateGetter(field)); } SetterDelegate ConfigureSetter() { if (IsConstantField()) { return((target, value) => throw new FieldAccessException($"Field {Name} cannot be set.")); } return(DelegatesFactory.CreateSetter(field)); } #endregion }
/// <summary> /// Constructor. /// </summary> /// <param name="property"><see cref="System.Reflection.PropertyInfo"/> to wrap.</param> internal ImmediateProperty([NotNull] PropertyInfo property) : base(property) { Debug.Assert(!IsIndexed(property), $"Cannot initialize an {nameof(ImmediateProperty)} with an indexed property."); // General property info PropertyInfo = property; PropertyType = property.PropertyType; #if SUPPORTS_LAZY _propertyImmediateType = new Lazy <ImmediateType>(() => TypeAccessor.Get(PropertyType)); #endif // ReSharper disable once AssignNullToNotNullAttribute, Justification: A property is always declared inside a type. DeclaringType = property.DeclaringType; CanRead = property.CanRead; CanWrite = property.CanWrite; // Getter / Setter _getter = ConfigureGetter(); _setter = ConfigureSetter(); #region Local functions GetterDelegate ConfigureGetter() { GetterDelegate getter = null; MethodInfo getMethod = property.GetGetMethod(true); if (getMethod != null) { getter = DelegatesFactory.CreateGetter(property, getMethod); } if (getter is null) { return(target => throw new ArgumentException($"No getter for property {Name}.")); } return(getter); } SetterDelegate ConfigureSetter() { SetterDelegate setter = null; MethodInfo setMethod = property.GetSetMethod(true); if (setMethod != null) { setter = DelegatesFactory.CreateSetter(property, setMethod); } if (setter is null) { return((target, value) => throw new ArgumentException($"No setter for property {Name}.")); } return(setter); } #endregion }