Length units converter I am creating a very small application to demonstrate solid principles and also a brief implementation of a builder pattern, does anyone have any feedback as to how this could be improved or how it breaks the solid principles? The app is a small app that just converts units, e.g. yards to meters, inches to cms.

Interface

public interface IConverter
{
    double ConversionRate { get; set; }
    string[] ConvertedUnits { get; set; }
    string DisplayText { get; set; }

    string[] Convert(string input);
}


Class implementing interface

 public class Converter : IConverter
    {
        public double ConversionRate { get; set; }
        public string[] ConvertedUnits { get; set; }
        public string DisplayText { get; set; }

        public Converter(double conversionRate, string[] convertedUnits, string displayText)
        {
            ConversionRate = conversionRate;
            ConvertedUnits = convertedUnits;
            DisplayText = displayText;
        }

        public string[] Convert(string input)
        {
            if (!input.Contains('\n'))
            {
                double d = double.Parse(input, CultureInfo.InvariantCulture) * ConversionRate;

                string[] array = new string[1];
                array[0] = d.ToString();

                return array;
            }
            else
            {
                double[] doubles = new double[input.Split('\n').Count()];

                for (int i = 0; i &lt; input.Split('\n').Count(); i++)
                {
                    double value = double.Parse(input.Split('\n')[i]);
                    doubles[i] = value;

                    string.Format("{0}", value * ConversionRate);
                }

                string[] strings = new string[doubles.Length];

                for (int i = 0; i &lt; input.Split('\n').Length; i++)
                {
                    strings[i] = string.Format("{0}", doubles[i] * ConversionRate);
                }

                return strings;
            }
        }
    }


Builder (abstract class)

public abstract class ConverterBuilder
    {
        protected double _conversionRate;
        protected string[] _convertedUnits;
        protected string _displayText;

        public ConverterBuilder AddConversionRate(double conversionRate)
        {
            _conversionRate = conversionRate;
            return this;
        }

        public ConverterBuilder AddConversionRate(string[] convertedUnits)
        {
            _convertedUnits = convertedUnits;
            return this;
        }

        public ConverterBuilder AddDisplayText(string displayText)
        {
            _displayText = displayText;
            return this;
        }

        public Converter Build()
        {
            return new Converter(_conversionRate, _convertedUnits, _displayText);
        }

    }


Builder implementing abstract builder class

public class UnitConverterBuilder : ConverterBuilder
{
    public UnitConverterBuilder()
    {

    }
}


Controller

public IActionResult Convert(string text, double conversionRate)
{
    Converter converter = new UnitConverterBuilder()
    .AddConversionRate(conversionRate)
    .Build();

    string output = "";
    for (int i = 0; i &lt; converter.Convert(text).Count(); i++)
    {
        output += converter.Convert(text)[i] + Environment.NewLine;
    }

    return Content(output);

}


View


    Enter values to convert

&lt;form asp-controller="Home" asp-action="Convert" method="post"&gt;
    &lt;textarea id="text" name="text" rows="10" cols="40"&gt;&lt;/textarea&gt;
    &lt;select name="conversionRate"&gt;
        &lt;option value=""&gt;Please Select&lt;/option&gt;
        &lt;option value="0.9144"&gt;Yards to Meters&lt;/option&gt;
        &lt;option value="2.54"&gt;Inches To Centimeters&lt;/option&gt;
    &lt;/select&gt;
    &lt;button&gt;Convert&lt;/button&gt;
&lt;/form&gt;




The app is built using .net core, any feedback greatly appreciated :)
Only targeting public string[] Convert(string input)  


Because this is a public method you should validate the input. Right now if one passes null this will throw an ArgumentNullException which isn't that bad but the stacktrace belongs to System.Linq.Enumerable.Contains() which you should hide.
Just testing against null or using string.IsNullOrWhiteSpace()` will do the trick.  
You are calling input.Split('\n') many many times. It would be much better to call it once and store the result in a variable.  
Don't use Count() method on an array, Using Count() use the Length property instead.  
You should use the overloaded Split() method which takes a [StringSplitOptions][2] enum like StringSplitOptions.RemoveEmptyEntries.  
Instead of using double.Parse() you should consider to use double.TryParse() which won't throw an exception if the current string doesn't represent a double like e.g a letter.  
This string.Format("{0}", value * ConversionRate); can be safely removed because the result isn't assigned to anything.  
Instead of returning a string[] you should consider to use an IEnumerable&lt;string or better just an IEnumerable&lt;double&gt; which is more straightforward. Sure that means you need to change your interface as well.  
Using a foreach will make the code shorter because you won't need to check for \n.  


Implementing the mentioned points will lead to 

string version 

public IEnumerable&lt;string&gt; Convert(string input)
{
    if (string.IsNullOrWhiteSpace(input))
    {
        yield break;
    }
    var values = input.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
    foreach (var value in values)
    {
        double current;
        if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out current))
        {
            yield return (current * ConversionRate).ToString();
        }
    }
}


double version  

    public IEnumerable&lt;double&gt; Convert(string input)
    {
        if (string.IsNullOrWhiteSpace(input))
        {
            yield break;
        }
        var values = input.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
        foreach (var value in values)
        {
            double current;
            if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out current))
            {
                yield return (current * ConversionRate);
            }
        }
    }




Ok, I need to target Controller.Convert() as well  

This is really really bad:  


string output = "";
for (int i = 0; i &lt; converter.Convert(text).Count(); i++)
{
    output += converter.Convert(text)[i] + Environment.NewLine;
}

return Content(output);  



Assume you have text = "\n1\n2\n3\n4\n5.......\n1000" then your code will once call converter.Convert() at
for (int i = 0; i &lt; converter.Convert(text).Count(); i++)
which results in Count() = 1000 hence the loop will be executed 1000 times which calls converter.Convert(text) 1000 times.
In addition using output += on strings will lead to very bad performance because each time a new string object is created because strings are immutable.
Better use a StringBuilder.

Assuming you use the IEnumerable&lt;double&gt; Convert() this will lead to  

    StringBuilder sb = new StringBuilder(1024);
    foreach (var value in converter.Convert(text))
    {
        sb.AppendLine(value.ToString());
    }

    return Content(sb.ToString());