有没有办法引用导致异常的对象?

问题描述

| 试图找到一种通过使用异常处理来处理我的部分数据验证的惰性方法。例如,如果文本框中的文本应该是字符串,则代码尝试在将其所有数字都解析为字符串时,将引发异常。从catch块中,是否可以引用问题对象并说...将其背景颜色更改为黄色?     

解决方法

您可以访问您的文本框对象,并且实际上在示例文本框中也不会引起异常。 WPF示例:
int number;
try
{
    number = int.Parse(textBox1.Text);
}
catch (FormatException)
{
    textBox1.Background = new SolidColorBrush(Colors.Red);
}
尽管对于此特定示例,最好改用
TryParse
。 如果您的对象仅在Validate方法内部可访问,并且validate方法失败,并且您想使此对象在
catch
内部可用,则需要实现自定义异常,在这种情况下,该异常将具有TextBox类型的字段。 [编辑] 我想我误解了这个问题。 自订例外
public class MyException : Exception
{
    public TextBox TextBox { get; private set; }

    public MyException(TextBox textBox)
    {
        TextBox = textBox;
    }
}
解析,验证或其他方法:
public int Parse()
{
    try
    {
        return int.Parse(textBox1.Text);
    }
    catch (FormatException)
    {
        throw new MyException(textBox1);
    }
}
用法:
    int number;
    try
    {
        number = int.Parse(textBox1.Text);
    }
    catch (MyException exception)
    {
        exception.TextBox.Background = new SolidColorBrush(Colors.Red);
    }
    ,不会。导致异常的对象很可能是某个对象的私有成员,并且通过允许通过异常处理程序公开它,您将破坏类的封装。     ,没有。 您需要记住,它不是导致异常的对象。这是引发异常的代码行。 您可以创建保存对象的自定义异常,然后发送回所选的对象。 (或该对象) 从MSDN:设计自定义异常 您可以通过内置功能获得的最接近的功能: Exception.Source属性     ,正如已经建议的那样,您可以创建自己的自定义异常,该异常可以传达正在验证的控件,然后使您能够对控件进行一些布局更改 但是我认为引发一个事件比引发一个异常要干净得多,在这种情况下,该事件可以将对象与验证错误进行通信。然后,您可以在事件订阅者中执行对象布局更改。 不过,最干净的方法是使用现有的ASP.NET验证控件。正则表达式验证器可以执行数字/非数字的实际测试,但是缺少挂钩布局更改的位置。为此,可以使用
CustomValidator
绑定bind7ѭ事件,并在检测到错误时设置控件布局。的 但是,如果您选择进行基于事件的验证,则尝试如下所示。
/// <summary>
/// Event args for the validation error. 
/// </summary>
/// <typeparam name=\"ControlType\">The control type accepted. (Can be \'Control´ for flexibility.</typeparam>
public class EvalidationErrorEventArgs<ControlType> : System.EventArgs
    where ControlType : Control
{
    ControlType ControlCausingException { get; private set; }

    public FormatException RaisedException { get; private set; }

    public EvalidationErrorEventArgs(ControlType controlCausingException,FormatException ex)
    {
        this.ControlCausingException = controlCausingException;
    }
}

/// <summary>
/// The validation error event.
/// </summary>
/// <typeparam name=\"ControlType\">The type of control to be communicated by the event.</typeparam>
/// <param name=\"sender\"></param>
/// <param name=\"e\"></param>
public delegate void ValidationErrorEvent<ControlType>(object sender,EvalidationErrorEventArgs<ControlType> e);

/// <summary>
/// Base validator,expects validation 
/// errors to be communicated as a FormatException. 
/// Other exception types are thrown.
/// </summary>
public abstract class TextBoxValidator
{
    public event ValidationErrorEvent<TextBox> ValidationError;

    /// <summary>
    /// Do validation. Raises event if format exception 
    /// occurs and listeners are registered. 
    /// </summary>
    /// <param name=\"textBoxToValidate\">Control to validate.</param>
    public void Validate(TextBox textBoxToValidate)
    {
        try
        {
            DoValidation(textBoxToValidate);
        }
        catch (FormatException e)
        {
            if (ValidationError != null)
            {
                ValidationError(this,new EvalidationErrorEventArgs<TextBox>(textBoxToValidate,e));
            }
            else
            {
                throw;
            }
        }
    }

    /// <summary>
    /// Overwrite to implement the actual 
    /// validation.
    /// </summary>
    /// <param name=\"txt\">Control to validate</param>
    protected abstract void DoValidation(TextBox txt);
}

/// <summary>
/// Performs validation of input controls content. 
/// </summary>
public abstract class IsTextValidator : TextBoxValidator
{
    /// <summary>
    /// Validates a text box to contain an integer value. 
    /// </summary>
    /// <param name=\"txt\">Control to validate</param>
    protected override void DoValidation(TextBox txt)
    {
        int.Parse(txt.Text);
    }
}