【问题标题】:Dictionary inherited from base class cannot be added to from derived class从基类继承的字典不能从派生类添加到
【发布时间】:2020-02-23 14:09:06
【问题描述】:

我有一个用于 PO 的抽象类。

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

这由两种不同类型的 PO 继承:CPO 和 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;
    }
  }
}

ValidatePONumber(value) 返回false 时,它会正确执行InvalidFields.Add(),但从未实际添加字典。在 Locals 窗口中,创建了一个名为 Namespace.PO.InvalidFields.get returned 的新变量,我可以看到添加的新键。但是,this.InvalidFields 没有值。

所以看起来抽象基类PO 中的字典被创建并添加到而不是派生类CPO

【问题讨论】:

  • 您在每次访问 InvalidFields 时都会创建一个新的 Dictionary&lt;string, object&gt;
  • 好的 - 所以=&gt; 符号实际上只是充当get?
  • 是的,prop =&gt; value;prop { get { return value; } } 一样

标签: c# .net


【解决方案1】:

您上面给出的代码甚至无法编译。您的派生类实际上并没有从抽象类继承(我假设它是一个错字)。即使在添加抽象类之后,字典实例化也会引发错误,因为它是属性定义并且缺少“set”定义(InvalidFields 缺少“set”访问器定义。

另外,这听起来是 Overriding fields or properties in subclasses 的副本

我已经尝试过稍作修改,请参阅下面的代码。就像@yransis 在 cmets 中所说,InvalidFields 被视为“获取”属性,每次执行“添加”步骤时都会返回字典的新实例。

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;
    }
}

调用这个类的主方法-

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();
}

在上面的代码中,我添加了明确的支持字段。它在构造函数中只被实例化一次。这样 InvalidFields 的内容是持久的。在您的代码中,您将返回一个新的字典实例,实际上丢失了存储在两个“get”调用之间的数据。

【讨论】:

    【解决方案2】:

    感谢 Klaus 指出问题。我通过设置一个私有 invalidFields 字段并使用 InvalidFields.get 返回它来解决,因为我正在做的是返回一个新的 Dictionary 类,每个 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;
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-10
      • 1970-01-01
      • 2014-12-23
      • 1970-01-01
      • 1970-01-01
      • 2012-09-07
      • 2017-04-14
      • 1970-01-01
      相关资源
      最近更新 更多