/// <summary> /// Constructs the implementations for all properties. /// </summary> /// <param name="pipeline">The implementation pipeline that consumes the methods.</param> /// <param name="classType">The base class of the type to generator properties for.</param> /// <param name="interfaceTypes">The interfaces where the properties originate.</param> /// <exception cref="InvalidOperationException"> /// Thrown if any property is declared as partially abstract. /// </exception> private void ConstructProperties ( [NotNull] ImplementationPipeline pipeline, [NotNull] Type classType, [NotNull] params Type[] interfaceTypes ) { var symbolTransformer = SymbolTransformer.Default; var properties = new List <PipelineWorkUnit <IntrospectivePropertyInfo> >(); foreach (var interfaceType in interfaceTypes) { foreach (var property in interfaceType.GetProperties()) { var targetProperty = property; // Skip properties with a managed implementation var baseClassProperty = classType.GetProperty(property.Name, property.PropertyType); if (!(baseClassProperty is null)) { var isFullyManaged = !baseClassProperty.GetGetMethod().IsAbstract&& !baseClassProperty.GetSetMethod().IsAbstract; if (isFullyManaged) { continue; } var isPartiallyAbstract = baseClassProperty.GetGetMethod().IsAbstract ^ baseClassProperty.GetSetMethod().IsAbstract; if (isPartiallyAbstract) { throw new InvalidOperationException ( "Properties with overriding managed implementations may not be partially managed." ); } targetProperty = baseClassProperty; } var definition = new IntrospectivePropertyInfo(targetProperty); properties.Add ( new PipelineWorkUnit <IntrospectivePropertyInfo> ( definition, symbolTransformer.GetTransformedSymbol(interfaceType, definition), Options ) ); } } pipeline.ConsumePropertyDefinitions(properties); }
/// <summary> /// Constructs the implementations for all properties. /// </summary> /// <param name="pipeline">The implementation pipeline that consumes the methods.</param> /// <param name="classType">The base class of the type to generator properties for.</param> /// <param name="interfaceTypes">The interfaces where the properties originate.</param> /// <exception cref="InvalidOperationException"> /// Thrown if any property is declared as partially abstract. /// </exception> private void ConstructProperties ( [NotNull] ImplementationPipeline pipeline, [NotNull] Type classType, [NotNull] params Type[] interfaceTypes ) { var constructedProperties = new List <IntrospectivePropertyInfo>(); var symbolTransformer = SymbolTransformer.Default; var properties = new List <PipelineWorkUnit <IntrospectivePropertyInfo> >(); foreach (var interfaceType in interfaceTypes) { foreach (var property in interfaceType.GetProperties().Select(p => new IntrospectivePropertyInfo(p))) { var targetProperty = property; // Skip methods that were already constructed - happens with inherited interfaces and multiple // identical definitions if (constructedProperties.Any(p => p.HasSameSignatureAs(property))) { continue; } // Skip properties with a managed implementation var baseClassProperty = classType.GetProperty(property.Name, property.PropertyType); if (!(baseClassProperty is null)) { var isFullyManaged = !baseClassProperty.GetGetMethod().IsAbstract&& !baseClassProperty.GetSetMethod().IsAbstract; if (isFullyManaged) { continue; } var isPartiallyAbstract = baseClassProperty.GetGetMethod().IsAbstract ^ baseClassProperty.GetSetMethod().IsAbstract; if (isPartiallyAbstract) { throw new InvalidOperationException ( "Properties with overriding managed implementations may not be partially managed." ); } targetProperty = new IntrospectivePropertyInfo(baseClassProperty); } properties.Add ( new PipelineWorkUnit <IntrospectivePropertyInfo> ( targetProperty, symbolTransformer.GetTransformedSymbol(interfaceType, targetProperty), Options ) ); constructedProperties.Add(targetProperty); } } pipeline.ConsumePropertyDefinitions(properties); }