Bread formula object I designed this object for a "bread formula". They use a concept known as baker's percentages, but you don't need to understand the math to help with the object design.

I designed it as an object (of type Formula) that contains objects (of type Ingredient).



Both classes have nullable properties. C# demarcates nullable types using a ? after the type, like so: 


public decimal? Weight { get; set; }



The reason I declare them as nullable types is because I don't know their values (when I create an instance of them) until I calculate them later, as which point I update the null value with a calculated value.

The calculations are just basic methods, like CalculateSum() or CalculateWeight().

Is there a better way to design this object? It works, but I feel like it's the wrong way to do things. I feel like I'm trying to force-fit inline/declarative style programming into an OOP design, but I don't know how else to do it, being so new to OOP.

My thinking is that this object has this property. I won't know its value when I create an instance of it, so I must declare it as nullable. Once I calculate its value using a method that's also internal to the class, I assign/set its value. Then it will no longer be null.

The calculation methods are basic calculations:


public type Method(input,input,...){calc; return calc;}.





 class Ingredient
    {
        public string Name { get; set; }
        public decimal Percentage { get; set; }
        public bool IsFlour { get; set; }
        public decimal? Weight { get; set; }

        public Ingredient(string _Name, decimal _Percent, bool _IsFlour, decimal? _Weight)
        {
            this.Name = _Name;
            this.Percentage = _Percent;
            this.IsFlour = _IsFlour;
            this.Weight = _Weight;
        }
    }

    class Formula
    {
        public decimal Weight_Total_Dough { get; set; }
        public ArrayList Ingredients { get; set; }
        public int NumberOfIngredients { get; set; }
        public decimal? SumPercentages { get; set; }
        public decimal? SumWeights { get; set; }
        public decimal? SumWeightTotalFlour { get; set; }

        public Formula(decimal _Weight_Total_Dough, ArrayList _Ingredients, int _NumberOfIngredients, decimal? _SumPercentages, decimal? _SumWeights, decimal? _SumWeightTotalFlour)
        {
            this.Weight_Total_Dough = _Weight_Total_Dough;
            this.Ingredients = _Ingredients;
            this.NumberOfIngredients = _NumberOfIngredients;
            this.SumPercentages = _SumPercentages;
            this.SumWeights = _SumWeights;
        }
    }


Here's the code for calculating Formula.SumPercentages, which was declared as nullable, but is now assigned a value:

public void SumPercentages(Formula f)
        {
            //Interate through Formula object, which contains an ArrayList of INGREDIENT objects.
            //Extract the precentages for each ingredient.
            //Add them up.
            //Return the summation as SumOfPercentages.

            decimal SumOfPercentages;
            SumOfPercentages = 0;
            foreach (object x in f.Ingredients) //for each INGREDIENT object in the FORMULA object
            {
                Ingredient ig = (Ingredient)x; //get the INGREDIENT.Percentage
                SumOfPercentages += ig.Percentage; //add it to the other INGREDIENT.Percentages
            }

            f.SumPercentages = SumOfPercentages; //SumOfPercentages was null before, but now we assign a value (SumOfPercentages) to it.
Everyone has had good ideas, but since you're asking about OOP, I'd suggest refactoring it altogether.

void Main()
{
    var formula = new Formula(new[] {
        new Ingredient("Flour, AP", 100m, true),
        new Ingredient("Water, Warm", 70.15m, false),
        new Ingredient("Salt", 3.04m, false),
        new Ingredient("Yeast", .24m, false),
        new Ingredient("Pate fermentee", 2.53m, false)
    });
    var weights = formula.GetWeights(10000m);
}

class Ingredient
{
    public string Name { get; private set; }
    public decimal Percentage { get; private set; }
    public bool IsFlour { get; private set; }

    public Ingredient(string _Name, decimal _Percent, bool _IsFlour)
    {
        this.Name = _Name;
        this.Percentage = _Percent;
        this.IsFlour = _IsFlour;
    }
}

class Formula
{
    private IEnumerable&lt;Ingredient&gt; Ingredients { get; set; }
    public decimal SumPercentages { get; private set; }

    public Formula(IEnumerable&lt;Ingredient&gt; _Ingredients)
    {
        this.Ingredients = _Ingredients;
        this.SumPercentages = _Ingredients.Sum(x =&gt; x.Percentage);
    }

    public Dictionary&lt;Ingredient, decimal&gt; GetWeights(decimal weightTotalDough)
    {
        return Ingredients.ToDictionary(k =&gt; k, v =&gt; (v.Percentage / this.SumPercentages) * weightTotalDough);
    }
}


By doing it this way, you separate the formula (which is basically just Ingredient/Percentage pairs) from each application of it.  You can use the same Formula object to calculate the weights for 10000g of dough or 50000g of dough - simply call GetWeights() with a different value.

Notice how many fewer properties you need on each class, and the question of "late setting" of some of them is entirely irrelevant.  Effectively, weight is not an intrinsic property of an ingredient, because it varies based on the total weight, so Weight shouldn't be a property of Ingredient.