public void IfIsAssignableFrom <TType>([NoEnumeration] object instance, string message = null) { if (ReferenceEquals(instance, null) || PortableTypeInfo.IsAssignableFrom(instance, typeof(TType))) { throw string.IsNullOrEmpty(message) ? new TException() : NewWithMessage(message); } }
public void GetPublicPropertyValue_ShouldGetAllValuesForMyClass() { var x = new MyClass { A = 21, B = "PINO", C = decimal.One, D = Math.PI }; var props = PortableTypeInfo.GetPublicProperties <MyClass>(); Assert.AreEqual(x.A, PortableTypeInfo.GetPublicPropertyValue(x, props.First(p => p.Name == nameof(MyClass.A)))); Assert.AreEqual(x.B, PortableTypeInfo.GetPublicPropertyValue(x, props.First(p => p.Name == nameof(MyClass.B)))); Assert.AreEqual(x.C, PortableTypeInfo.GetPublicPropertyValue(x, props.First(p => p.Name == nameof(MyClass.C)))); Assert.AreEqual(x.D, PortableTypeInfo.GetPublicPropertyValue(x, props.First(p => p.Name == nameof(MyClass.D)))); #if !(NETSTD10 || NETSTD11) var typeAccessor = Thrower.Reflection.FastMember.TypeAccessor.Create <MyClass>(); Assert.AreEqual(x.A, PortableTypeInfo.GetPublicPropertyValue(typeAccessor, x, props.First(p => p.Name == nameof(MyClass.A)))); Assert.AreEqual(x.B, PortableTypeInfo.GetPublicPropertyValue(typeAccessor, x, props.First(p => p.Name == nameof(MyClass.B)))); Assert.AreEqual(x.C, PortableTypeInfo.GetPublicPropertyValue(typeAccessor, x, props.First(p => p.Name == nameof(MyClass.C)))); Assert.AreEqual(x.D, PortableTypeInfo.GetPublicPropertyValue(typeAccessor, x, props.First(p => p.Name == nameof(MyClass.D)))); #endif }
private static bool IsFullyPublic(Type type, PropertyInfo[] props, bool allowNonPublicAccessors) { while (PortableTypeInfo.IsNestedPublic(type)) { type = type.DeclaringType; } if (!PortableTypeInfo.IsPublic(type)) { return(false); } if (allowNonPublicAccessors) { for (int i = 0; i < props.Length; i++) { if (props[i].GetGetMethod(true) != null && props[i].GetGetMethod(false) == null) { return(false); // non-public getter } if (props[i].GetSetMethod(true) != null && props[i].GetSetMethod(false) == null) { return(false); // non-public setter } } } return(true); }
/// <summary> /// Throws an exception of type <typeparamref name="TException"/> if and only if specified /// object has not given type. /// </summary> /// <param name="instance">The object to be tested.</param> /// <param name="type">The type the object must not have.</param> /// <param name="message">The optional message.</param> /// <exception cref="Exception"> /// If given condition is true, an exception of type <typeparamref name="TException"/> is thrown. /// </exception> public void IfIsNotInstanceOf([NoEnumeration] object instance, Type type, string message = null) { if (!PortableTypeInfo.IsInstanceOf(instance, type)) { throw string.IsNullOrEmpty(message) ? new TException() : NewWithMessage(message); } }
/// <summary> /// Formats given key-value pair in order to use it for <see cref="object.ToString"/>. /// </summary> /// <param name="pair">Key-value pair.</param> /// <returns>Formatted key-value pair.</returns> public static string ToString(KeyValuePair <string, object> pair) { var k = pair.Key; var v = pair.Value; if (v == null) { return($"{k}: null"); } var s = v as string; if (s != null) { return($"{k}: \"{s}\""); } var t = v.GetType(); if (PortableTypeInfo.IsPrimitive(t)) { return($"{k}: {v}"); } return($"{k}: {{{v}}}"); }
public void GetPublicProperties_ShouldReturnAllPropertiesOfMyInterface() { var props = PortableTypeInfo.GetPublicProperties <MyInterface>(); Assert.AreEqual(1, props.Count(p => p.Name == nameof(MyInterface.A))); Assert.AreEqual(1, props.Count(p => p.Name == nameof(MyInterface.B))); Assert.AreEqual(1, props.Count(p => p.Name == nameof(MyInterface.C))); }
public void GetPublicProperties_ShouldReturnAllPropertiesOfMyStruct() { var props = PortableTypeInfo.GetPublicProperties <MyStruct>(); Assert.AreEqual(1, props.Count(p => p.Name == nameof(MyStruct.A))); Assert.AreEqual(1, props.Count(p => p.Name == nameof(MyStruct.B))); Assert.AreEqual(1, props.Count(p => p.Name == nameof(MyStruct.C))); Assert.AreEqual(0, props.Count(p => p.Name == "P")); }
/// <summary> /// Ensures given enumeration value is defined in specified enumeration type. /// </summary> /// <typeparam name="TEnum">The enumeration type.</typeparam> /// <param name="value">The enumeration value.</param> /// <returns> /// True if given enumeration value is defined in specified enumeration type, false otherwise. /// </returns> /// <remarks>This also works when enumeration has been decorated with <see cref="FlagsAttribute"/>.</remarks> public static bool Validate <TEnum>(TEnum?value) where TEnum : struct { if (!PortableTypeInfo.IsEnum(CachedEnumValidator <TEnum> .EnumType)) { return(false); } return(value.HasValue ? Validate(value.Value) : true); }
private static ConstructorInfo GetCtor(IList <Type> ctorTypes) { return((from c in PortableTypeInfo.GetConstructors(typeof(TEx)) let args = c.GetParameters() let zipArgs = MyZip(args, ctorTypes, (argType, ctorType) => new { argType, ctorType }) where args.Length == ctorTypes.Count && (c.IsPublic || c.IsAssembly) && zipArgs.All(t => ReferenceEquals(t.argType.ParameterType, t.ctorType)) select c).FirstOrDefault()); }
public void GetPublicProperties_ShouldReturnAllPropertiesOfMyClass() { var props = PortableTypeInfo.GetPublicProperties <MyClass>(); Assert.AreEqual(1, props.Count(p => p.Name == nameof(MyClass.A))); Assert.AreEqual(1, props.Count(p => p.Name == nameof(MyClass.B))); Assert.AreEqual(1, props.Count(p => p.Name == nameof(MyClass.C))); Assert.AreEqual(1, props.Count(p => p.Name == nameof(MyAbstractClass.D))); Assert.AreEqual(0, props.Count(p => p.Name == "P")); }
/// <summary> /// Ensures given enumeration value is defined in specified enumeration type. /// </summary> /// <param name="enumType">The enumeration type.</param> /// <param name="value">The enumeration value.</param> /// <returns> /// True if given enumeration value is defined in specified enumeration type, false otherwise. /// </returns> /// <remarks>This also works when enumeration has been decorated with <see cref="FlagsAttribute"/>.</remarks> public static bool Validate(Type enumType, object value) { bool?isReallyAnEnum = null; if (PortableTypeInfo.IsGenericType(enumType) && ReferenceEquals(PortableTypeInfo.GetGenericTypeDefinition(enumType), typeof(Nullable <>))) { var innerEnumType = PortableTypeInfo.GetGenericTypeArguments(enumType)[0]; isReallyAnEnum = PortableTypeInfo.IsEnum(innerEnumType); if (isReallyAnEnum.Value && ReferenceEquals(value, null)) { // Nullable enum with null value, OK. return(true); } if (value.GetType() == enumType) { if (!PortableTypeInfo.GetPublicPropertyValue <bool>(value, nameof(Nullable <byte> .HasValue))) { // OK if we are really handling an enumeration. return(isReallyAnEnum.Value); } value = PortableTypeInfo.GetPublicPropertyValue(value, nameof(Nullable <byte> .Value)); } // Overwrite enumeration type with the inner one, since we are sure that value has // that type; in fact, above if ensures that condition. enumType = innerEnumType; } if ((isReallyAnEnum.HasValue && !isReallyAnEnum.Value) || !PortableTypeInfo.IsEnum(enumType)) { // If we are not handling an enum, then exit now. return(false); } if (Enum.IsDefined(enumType, value)) { return(true); } var hasFlagsAttribute = TypeHasFlagsAttribute(enumType); if (hasFlagsAttribute) { var mask = 0; foreach (var enumValue in Enum.GetValues(enumType)) { mask = mask | (int)enumValue; } var intValue = (int)value; return((mask & intValue) == intValue); } return(false); }
/// <summary> /// Ensures given enumeration value is defined in specified enumeration type. /// </summary> /// <typeparam name="TEnum">The enumeration type.</typeparam> /// <param name="value">The enumeration value.</param> /// <returns> /// True if given enumeration value is defined in specified enumeration type, false otherwise. /// </returns> /// <remarks>This also works when enumeration has been decorated with <see cref="FlagsAttribute"/>.</remarks> public static bool Validate <TEnum>(TEnum value) where TEnum : struct { if (!PortableTypeInfo.IsEnum(CachedEnumValidator <TEnum> .EnumType)) { return(false); } if (Enum.IsDefined(CachedEnumValidator <TEnum> .EnumType, value)) { return(true); } if (CachedEnumValidator <TEnum> .HasFlagsAttribute) { var intValue = PortableTypeInfo.CastTo <int> .From(value); return((CachedEnumValidator <TEnum> .Mask & intValue) == intValue); } return(false); }
private static void Cast(ILGenerator il, Type type, bool valueAsPointer) { if (type == typeof(object)) { } else if (PortableTypeInfo.IsValueType(type)) { if (valueAsPointer) { il.Emit(OpCodes.Unbox, type); } else { il.Emit(OpCodes.Unbox_Any, type); } } else { il.Emit(OpCodes.Castclass, type); } }
/// <summary> /// Converts given string into the specified enumeration value, applying the specified /// filter on casing. /// </summary> /// <typeparam name="TEnum">The type of the enumeration.</typeparam> /// <param name="enumString">The string value of one enumeration value.</param> /// <param name="ignoreCase">Whether to consider casing or not while parsing the string.</param> /// <returns>An enumeration value parsed from given string.</returns> /// <exception cref="InvalidOperationException"> /// Given type parameter <typeparamref name="TEnum"/> is not an enum. /// </exception> /// <exception cref="ArgumentException"> /// Given value cannot be mapped to any enum value. /// </exception> public static TEnum ToEnum <TEnum>(this string enumString, bool ignoreCase) where TEnum : struct { var enumType = typeof(TEnum); Raise.InvalidOperationException.IfNot(PortableTypeInfo.IsEnum(enumType), "Given type is not an enumeration"); #if NET35 var enumValue = Enum.Parse(enumType, enumString, ignoreCase); if (Enum.IsDefined(enumType, enumValue)) { return((TEnum)enumValue); } #else TEnum enumValue; if (Enum.TryParse(enumString, ignoreCase, out enumValue)) { return(enumValue); } #endif throw new ArgumentException($"Given value is not available for {enumType.Name}", nameof(enumString)); }
/// <summary> /// Converts given string into the specified enumeration value, applying the specified /// filter on casing. If given string cannot be mapped to any enum value, then default /// value for <typeparamref name="TEnum"/> is returned. /// </summary> /// <typeparam name="TEnum">The type of the enumeration.</typeparam> /// <param name="enumString">The string value of one enumeration value.</param> /// <param name="ignoreCase">Whether to consider casing or not while parsing the string.</param> /// <returns> /// An enumeration value parsed from given string or default enum value if that is not possible. /// </returns> /// <exception cref="InvalidOperationException"> /// Given type parameter <typeparamref name="TEnum"/> is not an enum. /// </exception> public static TEnum ToEnumOrDefault <TEnum>(this string enumString, bool ignoreCase) where TEnum : struct { var enumType = typeof(TEnum); Raise.InvalidOperationException.IfNot(PortableTypeInfo.IsEnum(enumType), "Given type is not an enumeration"); #if NET35 var enumValue = Enum.Parse(enumType, enumString, ignoreCase); if (Enum.IsDefined(enumType, enumValue)) { return((TEnum)enumValue); } #else TEnum enumValue; if (Enum.TryParse(enumString, ignoreCase, out enumValue)) { return(enumValue); } #endif // Not found, return default value. return(default(TEnum)); }
public void GetBaseType_ShouldReturnMyAbstractClass() { Assert.AreSame(typeof(MyAbstractClass), PortableTypeInfo.GetBaseType(typeof(MyClass))); }
public void IsValueType_ShouldReturnTrueWithStruct() { Assert.IsTrue(PortableTypeInfo.IsValueType(typeof(MyStruct))); Assert.IsTrue(PortableTypeInfo.IsValueType <MyStruct>()); }
public void IsPrimitive_ShouldReturnFalseWithEnum() { Assert.IsFalse(PortableTypeInfo.IsPrimitive(typeof(MyEnum))); Assert.IsFalse(PortableTypeInfo.IsPrimitive <MyEnum>()); }
private static bool ValidateInternal(object obj, string path, ValidateAttribute validation, IList <ValidationError> validationErrors) { if (ReferenceEquals(obj, null)) { if (validation.Required) { validationErrors.Add(new ValidationError(path, "Property is required, found null")); return(false); } // If object is null, we cannot do anything else. return(true); } var objType = obj.GetType(); if (AlwaysValidTypes.Contains(objType) || PortableTypeInfo.IsEnum(objType)) { return(true); } var isValueType = PortableTypeInfo.IsValueType(objType); // Check whether this type is nullable. if (validation.Required && isValueType && PortableTypeInfo.IsGenericType(objType) && objType.GetGenericTypeDefinition() == typeof(Nullable <>)) { var nullableProps = PortableTypeInfo.GetPublicProperties(objType); var nullableHasValueProp = nullableProps.First(p => p.Name == nameof(Nullable <bool> .HasValue)); if ((bool)PortableTypeInfo.GetPublicPropertyValue(obj, nullableHasValueProp)) { validationErrors.Add(new ValidationError(path, "Property is required, found null")); return(false); } var nullableValueProp = nullableProps.First(p => p.Name == nameof(Nullable <bool> .Value)); var nullableValue = PortableTypeInfo.GetPublicPropertyValue(obj, nullableValueProp); return(ValidateInternal(nullableValue, path, validation, validationErrors)); } var collection = obj as ICollection; if (collection != null) { var c = collection.Count; if (c < validation.CollectionItemsMinCount) { validationErrors.Add(new ValidationError(path, $"Minimum item count is {validation.CollectionItemsMinCount}, found {c}")); } if (c > validation.CollectionItemsMaxCount) { validationErrors.Add(new ValidationError(path, $"Maximum item count is {validation.CollectionItemsMaxCount}, found {c}")); } } var enumerable = obj as IEnumerable; if (enumerable != null && validation.Enumerable) { var itemValidation = new ValidateAttribute { Required = validation.EnumerableItemsRequired }; var index = 0; foreach (var item in enumerable) { var indexedNewPath = $"{path}[{index++}]"; ValidateInternal(item, indexedNewPath, itemValidation, validationErrors); } } if (PortableTypeInfo.IsClass(objType) || isValueType) { var props = PortableTypeInfo.GetPublicProperties(objType); var reqProps = from p in props from a in PortableTypeInfo.GetCustomAttributes(p, false) let v = a as ValidateAttribute where v != null select new { PropertyInfo = p, Validation = v }; #if !(NETSTD10 || NETSTD11) && FAST_MEMBER var typeAccessor = Reflection.FastMember.TypeAccessor.Create(objType); #endif foreach (var rp in reqProps) { var propertyInfo = rp.PropertyInfo; #if !(NETSTD10 || NETSTD11) && FAST_MEMBER var propertyValue = PortableTypeInfo.GetPublicPropertyValue(typeAccessor, obj, propertyInfo); #else var propertyValue = PortableTypeInfo.GetPublicPropertyValue(obj, propertyInfo); #endif var newPath = $"{path}.{propertyInfo.Name}"; ValidateInternal(propertyValue, newPath, rp.Validation, validationErrors); } return(validationErrors.Count == 0); } // Non dovrei mai finire qui! return(true); }
public void IsPrimitive_ShouldReturnFalseWithInterface() { Assert.IsFalse(PortableTypeInfo.IsPrimitive(typeof(MyInterface))); }
public void IsPrimitive_ShouldReturnFalseWithStruct() { Assert.IsFalse(PortableTypeInfo.IsPrimitive(typeof(MyStruct))); Assert.IsFalse(PortableTypeInfo.IsPrimitive <MyStruct>()); }
public void IsPrimitive_ShouldReturnFalseWithAbstractClass() { Assert.IsFalse(PortableTypeInfo.IsPrimitive(typeof(MyAbstractClass))); }
private static bool TypeHasFlagsAttribute(Type enumType) => PortableTypeInfo .GetCustomAttributes(enumType, true) ?.Any(a => a is FlagsAttribute) ?? false;
public void IsPrimitive_ShouldReturnTrueWithPrimitive() { Assert.IsTrue(PortableTypeInfo.IsPrimitive(typeof(int))); Assert.IsTrue(PortableTypeInfo.IsPrimitive <int>()); }
private static TypeAccessor CreateNew(Type type, bool allowNonPublicAccessors) { #if !NET35 if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type)) { return(DynamicAccessor.Singleton); } #endif var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); var map = new Dictionary <string, int>(); var members = new List <MemberInfo>(props.Length + fields.Length); var i = 0; foreach (var prop in props) { if (!map.ContainsKey(prop.Name) && prop.GetIndexParameters().Length == 0) { map.Add(prop.Name, i++); members.Add(prop); } } foreach (var field in fields) { if (!map.ContainsKey(field.Name)) { map.Add(field.Name, i++); members.Add(field); } } ConstructorInfo ctor = null; if (PortableTypeInfo.IsClass(type) && !PortableTypeInfo.IsAbstract(type)) { ctor = type.GetConstructor(PortableTypeInfo.EmptyTypes); } ILGenerator il; if (!IsFullyPublic(type, props, allowNonPublicAccessors)) { var dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(int), typeof(object) }, type, true); var dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(int), typeof(object), typeof(object) }, type, true); WriteMapImpl(dynGetter.GetILGenerator(), type, members, null, allowNonPublicAccessors, true); WriteMapImpl(dynSetter.GetILGenerator(), type, members, null, allowNonPublicAccessors, false); DynamicMethod dynCtor = null; if (ctor != null) { dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), PortableTypeInfo.EmptyTypes, type, true); il = dynCtor.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); } return(new DelegateAccessor( map, (Func <int, object, object>)dynGetter.CreateDelegate(typeof(Func <int, object, object>)), (Action <int, object, object>)dynSetter.CreateDelegate(typeof(Action <int, object, object>)), dynCtor == null ? null : (Func <object>)dynCtor.CreateDelegate(typeof(Func <object>)), type)); } // note this region is synchronized; only one is being created at a time so we don't need // to stress about the builders if (assembly == null) { var name = new AssemblyName("FastMember_dynamic"); #if (NETSTD13 || NETSTD20) assembly = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); #else assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); #endif module = assembly.DefineDynamicModule(name.Name); } #if (NETSTD13 || NETSTD20) var attribs = typeof(TypeAccessor).GetTypeInfo().Attributes; #else var attribs = typeof(TypeAccessor).Attributes; #endif var tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + GetNextCounterValue(), (attribs | TypeAttributes.Sealed | TypeAttributes.Public) & ~(TypeAttributes.Abstract | TypeAttributes.NotPublic), typeof(RuntimeTypeAccessor)); il = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { typeof(Dictionary <string, int>) }).GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); var mapField = tb.DefineField("_map", typeof(Dictionary <string, int>), FieldAttributes.InitOnly | FieldAttributes.Private); il.Emit(OpCodes.Stfld, mapField); il.Emit(OpCodes.Ret); var indexer = typeof(TypeAccessor).GetProperty("Item"); var baseGetter = indexer.GetGetMethod(); var baseSetter = indexer.GetSetMethod(); var body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] { typeof(object), typeof(string) }); il = body.GetILGenerator(); WriteMapImpl(il, type, members, mapField, allowNonPublicAccessors, true); tb.DefineMethodOverride(body, baseGetter); body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) }); il = body.GetILGenerator(); WriteMapImpl(il, type, members, mapField, allowNonPublicAccessors, false); tb.DefineMethodOverride(body, baseSetter); MethodInfo baseMethod; if (ctor != null) { baseMethod = typeof(TypeAccessor).GetProperty(nameof(CreateNewSupported)).GetGetMethod(); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, PortableTypeInfo.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); baseMethod = typeof(TypeAccessor).GetMethod(nameof(CreateNew)); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, PortableTypeInfo.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); } baseMethod = typeof(RuntimeTypeAccessor).GetProperty("Type", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.ReturnType, PortableTypeInfo.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldtoken, type); il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); #if (NETSTD13 || NETSTD20) var typeToBeCreated = tb.CreateTypeInfo().AsType(); #else var typeToBeCreated = tb.CreateType(); #endif var accessor = (TypeAccessor)Activator.CreateInstance(typeToBeCreated, map); return(accessor); }
private static void WriteMapImpl(ILGenerator il, Type type, List <MemberInfo> members, FieldBuilder mapField, bool allowNonPublicAccessors, bool isGet) { OpCode obj, index, value; var fail = il.DefineLabel(); if (mapField == null) { index = OpCodes.Ldarg_0; obj = OpCodes.Ldarg_1; value = OpCodes.Ldarg_2; } else { il.DeclareLocal(typeof(int)); index = OpCodes.Ldloc_0; obj = OpCodes.Ldarg_1; value = OpCodes.Ldarg_3; il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, mapField); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldloca_S, (byte)0); il.EmitCall(OpCodes.Callvirt, tryGetValue, null); il.Emit(OpCodes.Brfalse, fail); } var labels = new Label[members.Count]; for (int i = 0; i < labels.Length; i++) { labels[i] = il.DefineLabel(); } il.Emit(index); il.Emit(OpCodes.Switch, labels); il.MarkLabel(fail); il.Emit(OpCodes.Ldstr, "name"); il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new Type[] { typeof(string) })); il.Emit(OpCodes.Throw); for (int i = 0; i < labels.Length; i++) { il.MarkLabel(labels[i]); var member = members[i]; var isFail = true; FieldInfo field; PropertyInfo prop; if ((field = member as FieldInfo) != null) { il.Emit(obj); Cast(il, type, true); if (isGet) { il.Emit(OpCodes.Ldfld, field); if (PortableTypeInfo.IsValueType(field.FieldType)) { il.Emit(OpCodes.Box, field.FieldType); } } else { il.Emit(value); Cast(il, field.FieldType, false); il.Emit(OpCodes.Stfld, field); } il.Emit(OpCodes.Ret); isFail = false; } else if ((prop = member as PropertyInfo) != null) { MethodInfo accessor; if (prop.CanRead && (accessor = isGet ? prop.GetGetMethod(allowNonPublicAccessors) : prop.GetSetMethod(allowNonPublicAccessors)) != null) { il.Emit(obj); Cast(il, type, true); if (isGet) { il.EmitCall(PortableTypeInfo.IsValueType(type) ? OpCodes.Call : OpCodes.Callvirt, accessor, null); if (PortableTypeInfo.IsValueType(prop.PropertyType)) { il.Emit(OpCodes.Box, prop.PropertyType); } } else { il.Emit(value); Cast(il, prop.PropertyType, false); il.EmitCall(PortableTypeInfo.IsValueType(type) ? OpCodes.Call : OpCodes.Callvirt, accessor, null); } il.Emit(OpCodes.Ret); isFail = false; } } if (isFail) { il.Emit(OpCodes.Br, fail); } } }
/// <summary> /// Gets attribute type. /// </summary> /// <param name="attributeType">The attribute type.</param> /// <param name="inherit"> /// If true, specifies to also search the ancestors of element for custom attributes. /// </param> public Attribute GetAttribute(Type attributeType, bool inherit) => PortableTypeInfo .GetCustomAttributes(member, inherit) .FirstOrDefault(a => PortableTypeInfo.IsInstanceOf(a, attributeType));
#pragma warning restore CC0022 // Should dispose object /// <summary> /// Creates a new ObjectReader instance for reading the supplied data. /// </summary> /// <param name="type">The expected Type of the information to be read.</param> /// <param name="source">The sequence of objects to represent.</param> /// <param name="members">The members that should be exposed to the reader.</param> public ObjectReader(Type type, IEnumerable source, params string[] members) { if (source == null) { throw new ArgumentOutOfRangeException(nameof(source)); } var allMembers = members == null || members.Length == 0; this._accessor = TypeAccessor.Create(type); if (_accessor.GetMembersSupported) { var typeMembers = this._accessor.GetMembers(); if (allMembers) { members = new string[typeMembers.Count]; for (int i = 0; i < members.Length; i++) { members[i] = typeMembers[i].Name; } } this._allowNull = new BitArray(members.Length); this._effectiveTypes = new Type[members.Length]; for (int i = 0; i < members.Length; i++) { Type memberType = null; var allowNull = true; var hunt = members[i]; foreach (var member in typeMembers) { if (member.Name == hunt) { if (memberType == null) { var tmp = member.Type; memberType = Nullable.GetUnderlyingType(tmp) ?? tmp; allowNull = !(PortableTypeInfo.IsValueType(memberType) && memberType == tmp); // but keep checking, in case of duplicates } else { memberType = null; // duplicate found; say nothing break; } } } this._allowNull[i] = allowNull; this._effectiveTypes[i] = memberType ?? typeof(object); } } else if (allMembers) { throw new InvalidOperationException("Member information is not available for this type; the required members must be specified explicitly"); } this._current = null; this._memberNames = (string[])members.Clone(); this._source = source.GetEnumerator(); }
public void IsValueType_ShouldReturnFalseWithClass() { Assert.IsFalse(PortableTypeInfo.IsValueType(typeof(MyClass))); }
public void IsValueType_ShouldReturnTrueWithEnum() { Assert.IsTrue(PortableTypeInfo.IsValueType(typeof(MyEnum))); Assert.IsTrue(PortableTypeInfo.IsValueType <MyEnum>()); }