c# - 捕获 PropertyInfo.setvalue 抛出的 setter 异常

标签 c#

我有这样一种情况,即在 ClassA 的 PropertyInfo 上围绕 SetValue 放置一个 try-catch 不会捕获 classA 属性的 setter 抛出的异常。我该如何解决这个案子?示例如下:

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


}

最佳答案

检查代码后,我认为问题出在 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 接收到 null 以外的值时,上面的代码将始终抛出 InvalidOperationException。如果您第一次设置它,它将始终有效,但以后不会。我打算建议重新安排您的 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 私有(private)。不幸的是,这将迫使您修改您打算执行的其余代码。没有太多信息,这是我最好的答案。请注意,按照惯例,我将抛出一个 ArgumentException,但您也可以抛出一个 ArgumentNullException。我选择前者是因为我使用了 String.IsNullOrWhiteSpace() 方法。

public class classA
{
    public string ID { get; private set; }

    public classA(string id)
    {
        if (String.IsNullOrWhiteSpace(id))
        {
            throw ArgumentException("id");
        }

        ID = id;
    }
}

关于c# - 捕获 PropertyInfo.setvalue 抛出的 setter 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24024571/

相关文章:

c# - OData 路径模板不是有效的 OData 路径模板

c# - 使用另一个被测试的函数来为实际测试做准备是不是单元测试的好方法?

c# - AJAX 回调到 ASP.NET Core Razor 页面的示例

c# - 透明图像上的红点

c# - 单个单词的正则表达式

c# - C#析构函数在哪里

c# - 如何使用c#读取EPS的属性或颜色信息?

c# - 找不到网络路径。提供程序 : Named Pipes Provider, 错误:40 - 无法打开与 SQL Server 的连接

C# 注册表搜索,从结果反向遍历

c# - Color.GetPixel().equals(Color.Blue) 的结果为 false