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

时间:2011-05-25 04:25:16

标签: c# exception reference

尝试通过使用异常处理找到一种处理部分数据验证的惰性方法。例如,如果文本框中的文本应该是一个字符串,代码会尝试将其解析为字符串,当它的所有数字时,它将抛出异常。从catch块中,有没有办法引用问题对象并说...将其背景颜色更改为黄色?

4 个答案:

答案 0 :(得分:0)

您可以访问文本框对象,实际上在您的示例文本框中也不会导致异常。

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

答案 1 :(得分:0)

没有。导致异常的对象可能是某个对象的私有成员,并且通过允许它通过异常处理程序公开,您将打破该类的封装。

答案 2 :(得分:0)

没有

您需要记住,它不是导致异常的对象。这是引发异常的一行代码。

您可以创建保存对象的custom exceptions,然后发送回选择的对象。 (或对象)

来自MSDN:Designing custom exceptions

最近,您可以使用内置功能:

Exception.Source Property

答案 3 :(得分:0)

正如已经建议的那样,您可以创建自己的自定义异常,该异常可以传达正在验证的控件,然后可以使您在控件上进行一些布局更改

但是我认为提出事件比提出异常更简洁,然后事件可以将对象与验证错误进行通信。然后,您可以在事件订阅者中执行对象布局更改。

最干净的事情是使用现有的ASP.NET验证控件。正则表达式验证器可以执行数字/非数字的实际测试,但缺少连接布局更改的位置。为此,您可以使用CustomValidator并绑定ServerValidate事件,并在该事件中检测到错误时设置控件布局。

但是,如果您选择进行基于事件的验证,则尝试如下所示。

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