【问题标题】:How to auto populate a property within a List property of a Class如何在类的 List 属性中自动填充属性
【发布时间】:2017-09-15 21:48:59
【问题描述】:

首先,提前感谢任何可以提供帮助的人。

我有一个标题和行方案。我希望 lines 对象使用来自 Header 的 headerId 自动填充。请问有人可以帮忙吗?

public class Header
{
    public int headerId { get; set; }
    public List<Lines> lines { get; set; }
}

public class Lines
{
    public int lineId { get; set; }
    public int headerId { get; set; }   //<<< want to autopopulate this from Header object
}

【问题讨论】:

  • 你用的是什么版本的visual studio?
  • 嗨,马特,VS2015
  • 你在哪里初始化Header类和列表?
  • 根据您的设计,您确实没有好的选择
  • 您可能需要重新考虑您的设计选择。理想情况下,由于您的 Header 类已经包含 headerId,因此没有理由将该变量传播到该列表中的每个 Lines 对象,因为它已经与 Header 的父类相关联。

标签: c# accessor class-properties


【解决方案1】:

有很多方法可以做到这一点。

选项 1 - 修复集合集。

public class Header
{
    private List<Lines> _lines
    public int HeaderId { get; set; }
    public List<Line> Lines 
    { 
        get { return _lines; }
        set 
        { 
            _lines = value;
            if(_lines != null)
            {
                foreach(var line in _lines)
                    line.HeaderId = HeaderId;
            }
        }
    }
}

public class Line
{
    public int LineId { get; set; }
    public int HeaderId { get; set; }  
}

这个路由的问题是只有在设置Lines集合时才设置HeaderId。这意味着您可以在事后更改它,否则您添加到 Lines 的任何新项目都不会被更正。

选项 2 - 构造线时传入标题

public class Header
{

    public int HeaderId { get; set; }
    public List<Line> Lines { get; set; }
}

public class Line
{
    public Header ParentHeader { get; }
    public int LineId { get; set; }
    public int? HeaderId { get { return ParentHeader?.HeaderId; }  

    public Line(Header header)
    {
        ParentHeader = header;
    }
}

只要所有行的Header 实例相同,如果您更改Header.HeaderId,所有行都会自动更新。

选项 3 - 不要将 Line 的实例直接添加到集合中

public class Header
{
    List<Line> _lines = new List<Line>();

    public int HeaderId { get; set; }
    public ReadOnlyCollection<Line> Lines { get {return _lines.AsReadOnly(); }


    public void AddLine(Line line)
    {               
        line.HeaderId = HeaderId;
        _lines.Add(line);
    }
}

这将与选项 1 具有相同的问题。

【讨论】:

  • 在选项 1 上,如果您将 Lines_set() 逻辑复制到 HeaderId_set() 函数,那么您可以使 Lines.HeaderID 与 Header.HeaderID 保持同步。 (从 Header 到 Line 的单向同步)
  • Sam Axe,也谢谢你的回复,我也试试看。
【解决方案2】:

你可以做这样的事情......

public class Header
{
    static int _headerIdSeed = 0;

    public int HeaderId { get; internal set; } = _headerIdSeed++;
    public IList<Line> Lines { get; } = new List<Line>();

    public Header Add(Line line)
    {
        line.HeaderId = this.HeaderId;
        this.Lines.Add(line);
        return this;
    }

    public Header Add(params Line[] lines)
    {
        return this.AddRange(lines);
    }

    public Header AddRange(IEnumerable<Line> lines)
    {
        foreach (var line in lines)
        {
            line.HeaderId = this.HeaderId;
            this.Lines.Add(line);
        }
        return this;
    }
}

public class Line
{
    static int _lineIdSeed = 0;
    public int LineId { get; internal set; } = _lineIdSeed++;
    public int HeaderId { get; internal set; }
}

...你可以这样使用它...

var header = new Header
{
    HeaderId = 1,
}.Add(new Line { },
      new Line { },
      new Line { });

foreach (var line in header.Lines)
    Console.WriteLine($"{line.HeaderId}-{line.LineId}");
/*
1-0
1-1
1-2
*/

【讨论】:

    猜你喜欢
    • 2015-06-21
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 2019-10-28
    相关资源
    最近更新 更多