在集合中的getter中过滤

问题描述 投票:-1回答:2
public Schedule 
{
    public Schedule()   
    {    
        Payments = new List<Payment>();
    }

    public List<Payment> Payments 
    {
        get => Payments.Where(x => x.IsActive).ToList();
        set { };
    }
}

我希望每当我收到它时,只从集合中返回Active付款。有没有办法让这项工作?问题是代码设置整个集合,并在整个应用程序中添加它,所以我不能只使用私有变量和调用

set { _payments = value }

换句话说,有些地方

Payments = new List<Payment>();
// elsewhere
Payments.Add(payment);

我想确保每当列表被引用时,只返回列表中返回的项目是IsActive

有谁知道如何使这项工作?

c# collections properties getter-setter
2个回答
2
投票

如果您希望Payments返回一个新集合,那么向该新集合添加项目不会改变您的类所拥有的集合。

这会奏效。

private List<Payment> _payments = new List<Payment>;

public IEnumerable<Payment> Payments => _payments.Where(x => x.IsActive);

public void AddPayment(Payment pmt) => _payments.Add(pmt);  

//  You can write ClearPayments(), RemovePayment(), etc.

你可能想要编写一个具有内部PaymentList : IList<T>的子类List<Payment>。它会对GetEnumerator()和索引器有特殊的行为,并简单地将其他所有内容转发给私有集合。当你开始思考它时,这需要做很多工作。

这取决于你真正需要的东西。如果你的代码的其余部分需要Schedule.Payments来返回可以被视为List<Payment>的东西,那么就必须改变一些东西。


3
投票

您希望提供对列表的受控访问,但您也提供对其的原始访问权限。

正如你已经想到的那样,这是行不通的。

我建议您通过提供方法隐藏实现的详细信息:

public Schedule 
{
    private List<Payment> _payments;
    public Schedule() 
    {
        _payments = new List<Payment>();
    }

    public IEnumerable<Payment> GetActivePayments()
    {
        //Do whatever you want here, e.g....
        return _payments.Where(x => x.IsActive).ToList();
    }

    public void AddPayment(Payment payment)
    {
        //Do whatever you want here, e.g....
        _payments.Add(payment);
    }

    public void ClearPayments()
    {
        //Do whatever you want here, e.g....
        _payments.Clear();
    }
}

或者,您可以创建自己的集合类并限制其中的数据处理。这些方面的东西:

public class PaymentList : IEnumerable<Payment>
{
    private List<Payment> _payments = new List<Payment>();

    public IEnumerator<Payment> GetEnumerator()
    {
        return _payments.Where(p => p.IsActive).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

用法:

var list = new PaymentList();
foreach (var item in list)
{
    //item would have IsActive = true
}
© www.soinside.com 2019 - 2024. All rights reserved.