Example #1
0
        /// <summary> Returns the element type of any class implementing <see cref="IEnumerable{T}" /> interface. Returns null when it is not found. </summary>
        public static TypeReference GetElementTypeFromIEnumerable(this SpecializedType collectionType, MetadataContext cx, bool allowIEnumerator, out bool?isGeneric)
        {
            bool foundNonGenericIEnumerable = false;

            foreach (var baseType in cx.GetBaseTypes(collectionType))
            {
                if (baseType.Type == TypeSignature.IEnumerableOfT || (allowIEnumerator && baseType.Type == TypeSignature.IEnumeratorOfT))
                {
                    isGeneric = true;
                    return(Assert.Single(baseType.TypeArguments));
                }
                if (baseType.Type == TypeSignature.IEnumerable || (allowIEnumerator && baseType.Type == TypeSignature.IEnumerator))
                {
                    foundNonGenericIEnumerable = true;
                }
            }
            // System.Collections.IEnumerable found in type hierarchy -> Object is element type.
            if (foundNonGenericIEnumerable)
            {
                isGeneric = false;
                return(TypeSignature.Object);
            }
            isGeneric = null;
            return(null);
        }
Example #2
0
        public static TypeDef AutoResolveImplementations(TypeDef type, MetadataContext cx)
        {
            var thisType   = type.Signature.SpecializeByItself();
            var baseTypes  = cx.GetBaseTypes(thisType).ToArray();
            var interfaces = cx.GetDirectImplements(thisType).ToArray();

            // exclude methods and properties that are already implemented
            var explicitImplMethods = new HashSet <MethodSignature>(type.Members.OfType <MethodDef>().SelectMany(m => m.Implements).Select(m => m.Signature));
            var explicitImplProps   = new HashSet <PropertySignature>(type.Members.OfType <PropertyDef>().SelectMany(m => m.Implements).Select(m => m.Signature));

            var methods    = baseTypes.Concat(interfaces).ZipSelectMany(t => cx.GetMemberMethodDefs(t.Type).Where(m => !explicitImplMethods.Contains(m))).ToLookup(m => m.Item2.Name);
            var properties = baseTypes.Concat(interfaces).ZipSelectMany(t => cx.GetMemberPropertyDefs(t.Type).Where(p => !explicitImplProps.Contains(p))).ToLookup(p => p.Item2.Name);

            var myMembers = type.Members.Select(member => {
                // implementations must be public
                if (member is MethodDef method && methods.Contains(method.Signature.Name))
                {
                    var mm = methods[method.Signature.Name]
                             .Where(m2 => m2.Item2.Params.Select(p => p.Type).SequenceEqual(method.Signature.Params.Select(p => p.Type)))
                             .Where(m2 => m2.Item2.ResultType == method.Signature.ResultType)
                             .Where(m2 => method.Signature.Accessibility == m2.Item2.Accessibility)
                             .Where(m2 => method.Signature.IsOverride || m2.Item2.DeclaringType.Kind == "interface")
                             .ToArray();
                    return(method.With(implements: method.Implements.AddRange(mm.Select(m => m.Item2.Specialize(m.Item1.TypeArguments, m.Item2.TypeParameters.Select(TypeReference.GenericParameter))))));
                }
Example #3
0
 /// <summary>
 /// Gets whether this type definition is derived from the base type definition.
 /// </summary>
 public static bool IsDerivedFrom(this SpecializedType type, SpecializedType baseType, MetadataContext cx)
 {
     if (type == null)
     {
         throw new ArgumentNullException("type");
     }
     if (baseType == null)
     {
         return(false);
     }
     return(cx.GetBaseTypes(type).Contains(baseType));
 }