private IMethodSymbol FindConstructorToDelegateTo( ImmutableArray <IParameterSymbol> parameters, ImmutableArray <TExpressionSyntax> expressions, ImmutableArray <IMethodSymbol> constructors, CancellationToken cancellationToken) { foreach (var constructor in constructors) { // Don't bother delegating to an implicit constructor. We don't want to add `: base()` as that's just // redundant for subclasses and `: this()` won't even work as we won't have an implicit constructor once // we add this new constructor. if (constructor.IsImplicitlyDeclared) { continue; } // Don't delegate to another constructor in this type if it's got the same parameter types as the // one we're generating. This can happen if we're generating the new constructor because parameter // names don't match (when a user explicitly provides named parameters). if (TypeToGenerateIn.Equals(constructor.ContainingType) && constructor.Parameters.Select(p => p.Type).SequenceEqual(ParameterTypes)) { continue; } if (GenerateConstructorHelpers.CanDelegateTo(_document, parameters, expressions, constructor) && !_service.WillCauseConstructorCycle(this, _document, constructor, cancellationToken)) { return(constructor); } } return(null); }
private bool IsCompatible(IMethodSymbol constructor, List <ITypeSymbol> parameterTypes) { Debug.Assert(constructor.Parameters.Length == parameterTypes.Count); // Don't delegate to another constructor in this type. if we're generating a new constructor with the // same parameter types. Note: this can happen if we're generating the new constructor because // parameter names don't match (when a user explicitly provides named parameters). if (TypeToGenerateIn.Equals(constructor.ContainingType) && constructor.Parameters.Select(p => p.Type).SequenceEqual(this.ParameterTypes)) { return(false); } var compilation = _document.SemanticModel.Compilation; for (var i = 0; i < constructor.Parameters.Length; i++) { var constructorParameter = constructor.Parameters[i]; var conversion = compilation.ClassifyCommonConversion(parameterTypes[i], constructorParameter.Type); if (!conversion.IsIdentity && !conversion.IsImplicit) { return(false); } } return(true); }