public IEnumerable <PropertyInfo> GetProperties(Type targetType, BindingFlags bindingAttr) { XValidation.ArgumentNotNull(targetType, nameof(targetType)); List <PropertyInfo> propertyInfos = new List <PropertyInfo>(targetType.GetProperties(bindingAttr)); // GetProperties on an interface doesn't return properties from its interfaces if (XTypesBasic.IsInterface(targetType)) { foreach (Type i in targetType.GetInterfaces()) { propertyInfos.AddRange(i.GetProperties(bindingAttr)); } } XProperties.Api.GetChildPrivateProperties(propertyInfos, targetType, bindingAttr); // a base class private getter/setter will be inaccessible unless the property was gotten from the base class for (int i = 0; i < propertyInfos.Count; i++) { PropertyInfo member = propertyInfos[i]; if (member.DeclaringType != targetType) { PropertyInfo declaredMember = (PropertyInfo)GetMemberInfoFromType(member.DeclaringType, member); propertyInfos[i] = declaredMember; } } return(propertyInfos); }
public ParametersMatchComparer(IList <Type> types, bool enableParamArray) { XValidation.ArgumentNotNull(types, nameof(types)); _types = types; _enableParamArray = enableParamArray; }
/// <summary> /// Gets the type of the typed collection's items. /// </summary> /// <param name="type">The type.</param> /// <returns>The type of the typed collection's items.</returns> public Type GetCollectionItemType(Type type) { XValidation.ArgumentNotNull(type, nameof(type)); Type genericListType; if (type.IsArray) { return(type.GetElementType()); } if (ImplementsGenericDefinition(type, typeof(IEnumerable <>), out genericListType)) { if (genericListType.IsGenericTypeDefinition()) { throw new Exception($"Type {type} is not a collection."); } return(genericListType.GetGenericArguments()[0]); } if (typeof(IEnumerable).IsAssignableFrom(type)) { return(null); } throw new Exception($"Type {type} is not a collection."); }
public void GetDictionaryKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType) { XValidation.ArgumentNotNull(dictionaryType, nameof(dictionaryType)); Type genericDictionaryType; if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary <,>), out genericDictionaryType)) { if (genericDictionaryType.IsGenericTypeDefinition()) { throw new Exception($"Type {dictionaryType} is not a dictionary."); } Type[] dictionaryGenericArguments = genericDictionaryType.GetGenericArguments(); keyType = dictionaryGenericArguments[0]; valueType = dictionaryGenericArguments[1]; return; } if (typeof(IDictionary).IsAssignableFrom(dictionaryType)) { keyType = null; valueType = null; return; } throw new Exception($"Type {dictionaryType} is not a dictionary."); }
private string FormatWith(string format, IFormatProvider provider, params object[] args) { // leave this a private to force code to use an explicit overload // avoids stack memory being reserved for the object array XValidation.ArgumentNotNull(format, nameof(format)); return(string.Format(provider, format, args)); }
public bool IsNullable(Type t) { XValidation.ArgumentNotNull(t, nameof(t)); if (t.IsValueType()) { return(IsNullableType(t)); } return(true); }
public bool HasDefaultConstructor(Type t, bool nonPublic) { XValidation.ArgumentNotNull(t, nameof(t)); if (t.IsValueType()) { return(true); } return(GetDefaultConstructor(t, nonPublic) != null); }
public Base64Encoder New(TextWriter writer) { XValidation.ArgumentNotNull(writer, nameof(writer)); Base64Encoder encoder = new Base64Encoder() { Writer = writer }; return(encoder); }
public bool InheritsGenericDefinition(Type type, Type genericClassDefinition, out Type implementingType) { XValidation.ArgumentNotNull(type, nameof(type)); XValidation.ArgumentNotNull(genericClassDefinition, nameof(genericClassDefinition)); if (!genericClassDefinition.IsClass() || !genericClassDefinition.IsGenericTypeDefinition()) { throw new ArgumentNullException($"'{genericClassDefinition}' is not a generic class definition."); } return(InheritsGenericDefinitionInternal(type, genericClassDefinition, out implementingType)); }
public MethodInfo GetBaseDefinition(PropertyInfo propertyInfo) { XValidation.ArgumentNotNull(propertyInfo, nameof(propertyInfo)); MethodInfo m = propertyInfo.GetGetMethod(true); if (m != null) { return(m.GetBaseDefinition()); } return(propertyInfo.GetSetMethod(true)?.GetBaseDefinition()); }
public IEnumerable <FieldInfo> GetFields(Type targetType, BindingFlags bindingAttr) { XValidation.ArgumentNotNull(targetType, nameof(targetType)); List <MemberInfo> fieldInfos = new List <MemberInfo>(targetType.GetFields(bindingAttr)); #if !PORTABLE // Type.GetFields doesn't return inherited private fields // manually find private fields from base class GetChildPrivateFields(fieldInfos, targetType, bindingAttr); #endif return(fieldInfos.Cast <FieldInfo>()); }
/// <summary> /// Returns a best method overload for given argument <paramref name="types"/>. /// </summary> /// <param name="candidates">List of method candidates.</param> /// <param name="types">Argument types.</param> /// <returns>Best method overload, or <c>null</c> if none matched.</returns> public static TMethod SelectMethod <TMethod>(IEnumerable <TMethod> candidates, IList <Type> types) where TMethod : MethodBase { XValidation.ArgumentNotNull(candidates, nameof(candidates)); XValidation.ArgumentNotNull(types, nameof(types)); // ParamArrays are not supported by ReflectionDelegateFactory // They will be treated like ordinary array arguments const bool enableParamArray = false; return(candidates .Where(m => FilterParameters(m.GetParameters(), types, enableParamArray)) .OrderBy(m => m.GetParameters(), new ParametersMatchComparer(types, enableParamArray)) .FirstOrDefault()); }
public ThreadSafeStore <TKey, TValue> ThreadSafeStore <TKey, TValue>(Func <TKey, TValue> creator) { XValidation.ArgumentNotNull(creator, nameof(creator)); return(new Models.E01D.Core.Collections.ThreadSafe.ThreadSafeStore <TKey, TValue>() { Creator = creator, //#if HAVE_CONCURRENT_DICTIONARY InternalStore = new ConcurrentDictionary <TKey, TValue>() //#else // InternalStore = new Dictionary<TKey, TValue>(); // Lock = new object(); //#endif }); }
/// <summary> /// Determines whether the member is an indexed property. /// </summary> /// <param name="member">The member.</param> /// <returns> /// <c>true</c> if the member is an indexed property; otherwise, <c>false</c>. /// </returns> public bool IsIndexedProperty(MemberInfo member) { XValidation.ArgumentNotNull(member, nameof(member)); PropertyInfo propertyInfo = member as PropertyInfo; if (propertyInfo != null) { return(IsIndexedProperty(propertyInfo)); } else { return(false); } }
/// <summary> /// Sets the member's value on the target object. /// </summary> /// <param name="member">The member.</param> /// <param name="target">The target.</param> /// <param name="value">The value.</param> public void SetMemberValue(MemberInfo member, object target, object value) { XValidation.ArgumentNotNull(member, nameof(member)); XValidation.ArgumentNotNull(target, nameof(target)); switch (member.MemberType()) { case MemberTypes.Field: ((FieldInfo)member).SetValue(target, value); break; case MemberTypes.Property: ((PropertyInfo)member).SetValue(target, value, null); break; default: throw new ArgumentException("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), nameof(member)); } }
public bool IsVirtual(PropertyInfo propertyInfo) { XValidation.ArgumentNotNull(propertyInfo, nameof(propertyInfo)); MethodInfo m = propertyInfo.GetGetMethod(true); if (m != null && m.IsVirtual) { return(true); } m = propertyInfo.GetSetMethod(true); if (m != null && m.IsVirtual) { return(true); } return(false); }
public bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition, out Type implementingType) { XValidation.ArgumentNotNull(type, nameof(type)); XValidation.ArgumentNotNull(genericInterfaceDefinition, nameof(genericInterfaceDefinition)); if (!genericInterfaceDefinition.IsInterface() || !genericInterfaceDefinition.IsGenericTypeDefinition()) { throw new ArgumentNullException($"'{genericInterfaceDefinition}' is not a generic interface definition."); } if (type.IsInterface()) { if (type.IsGenericType()) { Type interfaceDefinition = type.GetGenericTypeDefinition(); if (genericInterfaceDefinition == interfaceDefinition) { implementingType = type; return(true); } } } foreach (Type i in type.GetInterfaces()) { if (i.IsGenericType()) { Type interfaceDefinition = i.GetGenericTypeDefinition(); if (genericInterfaceDefinition == interfaceDefinition) { implementingType = i; return(true); } } } implementingType = null; return(false); }
public bool IsDictionaryType(Type type) { XValidation.ArgumentNotNull(type, nameof(type)); if (typeof(IDictionary).IsAssignableFrom(type)) { return(true); } if (ImplementsGenericDefinition(type, typeof(IDictionary <,>))) { return(true); } #if HAVE_READ_ONLY_COLLECTIONS if (ImplementsGenericDefinition(type, typeof(IReadOnlyDictionary <,>))) { return(true); } #endif return(false); }
/// <summary> /// Gets the member's underlying type. /// </summary> /// <param name="member">The member.</param> /// <returns>The underlying type of the member.</returns> public Type GetMemberUnderlyingType(MemberInfo member) { XValidation.ArgumentNotNull(member, nameof(member)); switch (member.MemberType()) { case MemberTypes.Field: return(((FieldInfo)member).FieldType); case MemberTypes.Property: return(((PropertyInfo)member).PropertyType); case MemberTypes.Event: return(((EventInfo)member).EventHandlerType); case MemberTypes.Method: return(((MethodInfo)member).ReturnType); default: throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo, EventInfo or MethodInfo", nameof(member)); } }
/// <summary> /// Gets the member's value on the object. /// </summary> /// <param name="member">The member.</param> /// <param name="target">The target object.</param> /// <returns>The member's value on the object.</returns> public object GetMemberValue(MemberInfo member, object target) { XValidation.ArgumentNotNull(member, nameof(member)); XValidation.ArgumentNotNull(target, nameof(target)); switch (member.MemberType()) { case MemberTypes.Field: return(((FieldInfo)member).GetValue(target)); case MemberTypes.Property: try { return(((PropertyInfo)member).GetValue(target, null)); } catch (TargetParameterCountException e) { throw new ArgumentException("MemberInfo '{0}' has index parameters".FormatWith(CultureInfo.InvariantCulture, member.Name), e); } default: throw new ArgumentException("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), nameof(member)); } }
/// <summary> /// Determines whether the property is an indexed property. /// </summary> /// <param name="property">The property.</param> /// <returns> /// <c>true</c> if the property is an indexed property; otherwise, <c>false</c>. /// </returns> public bool IsIndexedProperty(PropertyInfo property) { XValidation.ArgumentNotNull(property, nameof(property)); return(property.GetIndexParameters().Length > 0); }
public Attribute[] GetAttributes(object attributeProvider, Type attributeType, bool inherit) { XValidation.ArgumentNotNull(attributeProvider, nameof(attributeProvider)); object provider = attributeProvider; // http://hyperthink.net/blog/getcustomattributes-gotcha/ // ICustomAttributeProvider doesn't do inheritance Type t = provider as Type; if (t != null) { object[] array = attributeType != null?t.GetCustomAttributes(attributeType, inherit) : t.GetCustomAttributes(inherit); Attribute[] attributes = array.Cast <Attribute>().ToArray(); #if (NET20 || NET35) // ye olde .NET GetCustomAttributes doesn't respect the inherit argument if (inherit && t.BaseType != null) { attributes = attributes.Union(GetAttributes(t.BaseType, attributeType, inherit)).ToArray(); } #endif return(attributes); } Assembly a = provider as Assembly; if (a != null) { return((attributeType != null) ? Attribute.GetCustomAttributes(a, attributeType) : Attribute.GetCustomAttributes(a)); } MemberInfo mi = provider as MemberInfo; if (mi != null) { return((attributeType != null) ? Attribute.GetCustomAttributes(mi, attributeType, inherit) : Attribute.GetCustomAttributes(mi, inherit)); } Module m = provider as Module; if (m != null) { return((attributeType != null) ? Attribute.GetCustomAttributes(m, attributeType, inherit) : Attribute.GetCustomAttributes(m, inherit)); } ParameterInfo p = provider as ParameterInfo; if (p != null) { return((attributeType != null) ? Attribute.GetCustomAttributes(p, attributeType, inherit) : Attribute.GetCustomAttributes(p, inherit)); } #if !PORTABLE40 ICustomAttributeProvider customAttributeProvider = (ICustomAttributeProvider)attributeProvider; object[] result = (attributeType != null) ? customAttributeProvider.GetCustomAttributes(attributeType, inherit) : customAttributeProvider.GetCustomAttributes(inherit); return((Attribute[])result); #else throw new Exception("Cannot get attributes from '{0}'.".FormatWith(CultureInfo.InvariantCulture, provider)); #endif }
public bool IsNullableType(Type t) { XValidation.ArgumentNotNull(t, nameof(t)); return(t.IsGenericType() && t.GetGenericTypeDefinition() == typeof(Nullable <>)); }
/// <summary> /// Checks if a set of values with given <paramref name="types"/> can be used /// to invoke a method with specified <paramref name="parameters"/>. /// </summary> /// <param name="parameters">Method parameters.</param> /// <param name="types">Argument types.</param> /// <param name="enableParamArray">Try to pack extra arguments into the last parameter when it is marked up with <see cref="ParamArrayAttribute"/>.</param> /// <returns><c>true</c> if method can be called with given arguments, <c>false</c> otherwise.</returns> private static bool FilterParameters(ParameterInfo[] parameters, IList <Type> types, bool enableParamArray) { XValidation.ArgumentNotNull(parameters, nameof(parameters)); XValidation.ArgumentNotNull(types, nameof(types)); if (parameters.Length == 0) { // fast check for parameterless methods return(types.Count == 0); } if (parameters.Length > types.Count) { // not all declared parameters were specified (optional parameters are not supported) return(false); } // check if the last parameter is ParamArray Type paramArrayType = null; if (enableParamArray) { ParameterInfo lastParam = parameters[parameters.Length - 1]; if (lastParam.ParameterType.IsArray && lastParam.IsDefined(typeof(ParamArrayAttribute))) { paramArrayType = lastParam.ParameterType.GetElementType(); } } if (paramArrayType == null && parameters.Length != types.Count) { // when there's no ParamArray, number of parameters should match return(false); } for (int i = 0; i < types.Count; i++) { Type paramType = (paramArrayType != null && i >= parameters.Length - 1) ? paramArrayType : parameters[i].ParameterType; if (paramType == types[i]) { // exact match with provided type continue; } if (paramType == typeof(object)) { // parameter of type object matches anything continue; } if (XBaseTypes.IsPrimitive(paramType)) { if (!XBaseTypes.IsPrimitive(types[i]) || !CanConvertPrimitive(types[i], paramType)) { // primitive parameter can only be assigned from compatible primitive type return(false); } } else { if (!paramType.IsAssignableFrom(types[i])) { return(false); } } } return(true); }
public int Compare(ParameterInfo[] parameters1, ParameterInfo[] parameters2) { XValidation.ArgumentNotNull(parameters1, nameof(parameters1)); XValidation.ArgumentNotNull(parameters2, nameof(parameters2)); // parameterless method wins if (parameters1.Length == 0) { return(-1); } if (parameters2.Length == 0) { return(1); } Type paramArrayType1 = null, paramArrayType2 = null; if (_enableParamArray) { ParameterInfo lastParam1 = parameters1[parameters1.Length - 1]; if (lastParam1.ParameterType.IsArray && lastParam1.IsDefined(typeof(ParamArrayAttribute))) { paramArrayType1 = lastParam1.ParameterType.GetElementType(); } ParameterInfo lastParam2 = parameters2[parameters2.Length - 1]; if (lastParam2.ParameterType.IsArray && lastParam2.IsDefined(typeof(ParamArrayAttribute))) { paramArrayType2 = lastParam2.ParameterType.GetElementType(); } // A method using params always loses to one not using params if (paramArrayType1 != null && paramArrayType2 == null) { return(1); } if (paramArrayType2 != null && paramArrayType1 == null) { return(-1); } } for (int i = 0; i < _types.Count; i++) { Type type1 = (paramArrayType1 != null && i >= parameters1.Length - 1) ? paramArrayType1 : parameters1[i].ParameterType; Type type2 = (paramArrayType2 != null && i >= parameters2.Length - 1) ? paramArrayType2 : parameters2[i].ParameterType; if (type1 == type2) { // exact match between parameter types doesn't change score continue; } // exact match with source type decides winner immediately if (type1 == _types[i]) { return(-1); } if (type2 == _types[i]) { return(1); } int r = ChooseMorePreciseType(type1, type2); if (r != 0) { // winner decided return(r); } } return(0); }