PropertyInfo.setvalue抛出的陷阱setter异常

时间:2014-06-03 20:42:27

标签: c#

我有一种情况,在classA的PropertyInfo上放置一个围绕SetValue的try-catch不会捕获setA为classA属性抛出的异常。我怎么陷入这种情况?示例如下:

  public class classA
{
    private string _ID;
    public string ID
    {
        get { return _ID; }
        set
        {
            if (_ID == null) _ID = value;
            else throw new InvalidOperationException();
        }

    }
}

public class classB
{
    public void DoMagic()
    {
        classA MyA = new classA();

        PropertyInfo pi = GetPropertyInfoForProperty(typeof(classA), "ID");
        try
        {
            pi.SetValue(MyA, "This works fine", null);
        }
        catch { }

        ///MyA.ID = "The first time you set it everything is cool.";

        try
        {
            MyA.ID = "This throws a handled exception.";
        }
        catch { }


        try
        {
            pi.SetValue(MyA, "This Throws and Unhandled Exception", null);
        }
        catch { }

    }

    private PropertyInfo GetPropertyInfoForProperty(Type type, string p)
    {
        foreach (var pi in type.GetProperties())
            if (pi.Name == p)
                return pi;
        return null;
    }


}

1 个答案:

答案 0 :(得分:0)

在查看代码之后,我认为问题是classA类的ID setter中的逻辑错误。目前代码是:

public class classA
{
    private string _ID;
    public string ID
    {
        get { return _ID; }
        set
        {
            if (_ID == null) _ID = value;
            else throw new InvalidOperationException();
        }

    }
}

当ID收到InvalidOperationException以外的值时,上述内容将始终抛出null。如果您是第一次设置它,它将始终有效,但不是后续时间。我打算建议你在你的setter中重新安排if语句,但后来我意识到你的意图可能只是使ID属性只能设置一次,如下所示,但是当你有了它时会抛出相同的异常尝试第一次设置它,所以这不起作用。

public class classA
{
    private string _ID;
    public string ID
    {
        get { return _ID; }
        set
        {
            // This will always throw an exception
            if (_ID == null) 
            {
                // Is this what you intended? 
                // That is, throw an InvalidOperationException if a null value is supplied?
                throw new InvalidOperationException();
            }

            _ID = value;
        }

    }
}

话虽如此,我仍然不清楚为什么ID应该只设置一次,假设我的理解是正确的,但你可以尝试修改你的逻辑,以便通过构造函数设置ID并制作ID setter { {1}}。不幸的是,这将迫使您修改您打算执行的其余代码。没有太多信息,这是我最好的答案。请注意,按惯例,我正在抛出private,但您也可以抛出ArgumentException。我对前者的决定是由于我使用了ArgumentNullException方法。

String.IsNullOrWhiteSpace()