0

I have an abstract class for POs.

public abstract class PO 
{
  public abstract Dictionary<string, object> InvalidFields { get; }
  public abstract string PONumber { get; set; }
}

Which is inherited by two different types of PO: CPO and POR.

public class CPO 
{
  private string poNumber;

  public override Dictionary<string, object> InvalidFields => new Dictionary<string, object>();
  public override string PONumber
  {
    get 
    {
      return poNumber;
    }
    set 
    {
      if (!ValidatePONumber(value)) InvalidFields.Add("CPO Number", value);
      poNumber = value;
    }
  }
}

When ValidatePONumber(value) returns false, it correctly executes InvalidFields.Add() but the dictionary is never actually added to. In the Locals window, a new variable is created named Namespace.PO.InvalidFields.get returned and I can see the new key that is added. However, this.InvalidFields has no values.

So it looks like the dict in the abstract base class PO is being created and added to instead of the derived class CPO.

ryansin
  • 1,735
  • 2
  • 26
  • 49

2 Answers2

0

The code as you have given above does not even compile. You derived class is not actually inheriting from the abstract class (I am assuming it is a typo). Even after addition abstract class, the dictionary instantiation throws an error because it is a property definition and missing 'set' definition (InvalidFields is missing 'set' accessor definition.

Also, this sounds to be a duplicate of Overriding fields or properties in subclasses

I have tried this with minor modifications, please see the code below. Like @yransis says in comments, The InvalidFields is being treated as a 'get' property, returning new instance of dictionary every time it is executing the 'Add' step.

class DerivedCpo : AbstractPo
{
    private string poNumber;
    private Dictionary<string, object> invalidFieldsBackingField;
    public override Dictionary<string, object> InvalidFields
    {
        get
        {
            return invalidFieldsBackingField;
        }
        set { this.invalidFieldsBackingField = value; }
    }

    public DerivedCpo()
    {
        this.InvalidFields = new Dictionary<string, object>();
    }
    public override string PoNumber
    {
        get { return poNumber;}
        set
        {
            if(!ValidatePONumber((value)))
                InvalidFields.Add("CPO Number", value);
            poNumber = value;
        }
    }



    private bool ValidatePONumber(string value)
    {
        if (string.IsNullOrEmpty(value))
        {
            return false;
        }

        if (value.Length > 5)
            return false;

        return true;
    }
}

Main method calling this class -

static void Main(string[] args)
{
    var po = new DerivedCpo();
    po.PoNumber = "test1";
    po.PoNumber = "thisistheinvalidfieldpo";

    if (po.InvalidFields != null && po.InvalidFields.Count > 0)
    {
        Console.WriteLine(@"There are {0} fields in invalidFields collection", Convert.ToString(po.InvalidFields.Count) );
    }

    Console.WriteLine("Press any key to continue.");
    Console.ReadKey();
}

In the code above I have added explicit backing field. It is being instantiated only once in the constructor. That way the contents of InvalidFields are persistent. In your code, you are returning a new instance of dictionary, essentially losing the data that was stored between two 'get' calls.

Amogh Sarpotdar
  • 544
  • 4
  • 15
0

Thanks to Klaus for pointing out the issue. I resolved by setting up a private invalidFields field and returning that with InvalidFields.get because what I was doing was returning a new Dictionary class with every get.

public class CPO : PO
{
  private string poNumber;
  private Dictionary<string, object> invalidFields = new Dictionary<string, object>();

  public override Dictionary<string, object> InvalidFields { get => invalidFields; }
  public override PONumber
  {
    get 
    {
      return poNumber;
    }
    set 
    {
      if (!ValidatePONumber(value)) InvalidFields.Add("CPO Number", value);
      poNumber = value;
    }
  }
}
ryansin
  • 1,735
  • 2
  • 26
  • 49