尽管有边界检查,但ArgumentOutOfRangeException

时间:2016-02-25 09:57:03

标签: c# winforms

我在winforms中创建了自定义按钮,其中我添加了一个自定义类列表的属性:# connect to key conn = boto.connect_s3() bucket = conn.get_bucket("MyBucket") my_key = Key(bucket) my_key.key = "myfile/demo.txt" # if key exists, then update the file & its metadata if my_key.exists(): new_meta_data = {"name": "xyz"} # update metadata my_key.copy("MyBucket", my_key.name, new_meta_data, preserve_acl=True) # update file content in S3 by using the local file demo.txt my_key.set_contents_from_filename("demo.txt") 以及只有当该列表中的项目已满足特定项目时才将项目添加到此列表的方法标准(lambda .where表达式)。 类List<Zasoby>是可序列化的。 在设计师中,我将第一个Zasob添加到此按钮的列表中,如下所示:

Zasob

...

bt01008xxx.Zasoby.Add(new Zasob { Lokalizacja = new Lokalizacja("01", "008", "000") });

...

public class ZasobSzczegolowoButton: Button, IAddZasoby
{

    private List<Zasob> _zasoby = new List<Zasob>(); //{ new Zasob { Lokalizacja = new Lokalizacja("01", "001", "000") } };


    [EditorBrowsable(EditorBrowsableState.Always)]
    [Browsable(true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    [Bindable(true)]
    public List<Zasob> Zasoby
    {
        get { return _zasoby; }
        set
        {
            _zasoby = value;
            if (_zasoby.Any()) BackColor = _zasoby.Sum(x => x.Ilosc) > 0 ? Color.Coral : Color.White;
        }
    }

    public void AddZasoby(List<Zasob> zasoby)
    {
        var buton = Name;
        if (_zasoby != null && _zasoby.Count != 0)
        {
            var szukaneZasoby =
                zasoby?.Where(
                    x =>
                        x.Lokalizacja.ObszarKod == _zasoby[0].Lokalizacja.ObszarKod &&
                        x.Lokalizacja.Segment1 == _zasoby[0].Lokalizacja.Segment1);
            if (szukaneZasoby == null) return;

            Zasoby.Clear();
            Zasoby.AddRange(szukaneZasoby);
        }
    }
}

现在每当我尝试使用方法AddZasoby时,我都会收到System.ArgumentOutOfRangeException。我检查列表中的null和计数项目,并在调试模式和shoud退出方法,但仍然以某种方式结束在方法的正文中与错误。 (请看下面的截图) 知道我做错了什么吗?

1

1 个答案:

答案 0 :(得分:2)

您正确检查列表中的计数,但使用代码Zasoby.Clear();,您可以再次清除成员变量_zasoby中的这些元素。

不要让它自己欺骗:你正在定义Where() - 之前的条款清除列表但是之后会执行!这就是lambdas的技巧,你在Where() - lambda中编写的谓词只会在评估后立即执行。

此功能称为延期执行,请参阅the first example here

要解决此问题,您可以在清除列表之前致电ToArray()ToList(),立即强制执行lambda:

  public void AddZasoby(List<Zasob> zasoby)
    {
        var buton = Name;
        if (_zasoby != null && _zasoby.Count != 0)
        {
            var szukaneZasoby =
                zasoby?.Where(
                    x =>
                        x.Lokalizacja.ObszarKod == _zasoby[0].Lokalizacja.ObszarKod &&
                        x.Lokalizacja.Segment1 == _zasoby[0].Lokalizacja.Segment1
                    ).ToList(); // *** NOTE ME HERE ***

            if (szukaneZasoby == null) return;

            Zasoby.Clear();
            Zasoby.AddRange(szukaneZasoby);
        }
    }

这应该可以解决问题。