我有一个自定义集合,我正在向其中添加 ValidateItem 事件。每当在自定义集合中添加或更新项目时,都会调用此 ValidateItem 事件。
我希望允许派生类能够订阅该事件并确定自己的逻辑来判断某个项目是否“有效”,并且如果该项目“无效”,则可能会禁止将其添加到集合中。
但我试图弄清楚如何让事件的调用者知道正在发生什么以及如何传递有关正在发生的事情的信息。
我的自定义事件参数继承自 CancelEventArgs,因此我能够使用它将取消位传递回调用者。但我从未见过任何错误信息(错误代码、消息等)以这种方式传回的情况,所以我想知道这是否不是最好的方法。
我是否应该添加任何我希望传递回自定义 eventargs 类的错误数据,是否有充分的理由支持或反对?或者还有其他更好的方法来实现这一点吗?
这是我的 eventargs 类:
public delegate void ItemValidationEventHandler(object sender, ItemValidationEventArgs e);
public class ItemValidationEventArgs : CancelEventArgs
{
public ItemValidationEventArgs(object item, ObjectAction state, EventArgs e)
{
Item = item;
State = state;
EventArgs = e;
}
public ItemValidationEventArgs(object item, ObjectAction state) : this(item, state, new EventArgs())
{
}
public ItemValidationEventArgs() : this(null, ObjectAction.None, new EventArgs())
{
}
// is there a better way to pass this info?
public string ErrorMessage {get; set;}
public int ErrorNumber {get;set;}
public object Item { get; private set; }
public ObjectAction State { get; private set; }
public EventArgs EventArgs { get; private set; }
}
更新:我想另一个选择是使用这样的东西:
virtual bool Validate(object item, ObjectAction action, out string errorMessage)
派生类中的方法。虽然我倾向于避免使用 out 参数...
如果有人对每种方法的优缺点有任何想法,我很想听听!
谢谢, 最大
最佳答案
为此使用事件可能不是最好的设计方法。
由于它是一个将重写此行为的继承类,因此该方法应标记为 protected 和 virtual:
protected virtual bool Validate(object item);
我也不喜欢在参数上使用 out
,因此按照您使用 EventArgs
的最初本能,您可能应该创建一个类来封装验证结果。
示例:
class ValidationResult
{
public string ResultMessage{get;set;}
public bool IsValid {get;set;}
}
你的方法将是:
protected virtual ValidationResult Validate(object item)
{
ValidationResult result = new ValidationResult();
// validate and set results values accordingly
return result;
}
使用事件而不是事件的优点和缺点是,当您想要向多个订阅者发布操作或信息时,可以使用事件。订阅者是您一无所知的类。你不关心他们是谁或他们做什么。他们也不应该真正将信息传递回通知类。他们应该只处理提供给他们的事件信息。
在您的实例中,您继承的类是您唯一的订阅者。最重要的是,您希望能够将有用的信息传递回父类。继承更适合这种期望的行为,并且还允许您轻松实现不同类型的验证类。对于事件,您必须一遍又一遍地不断键入代码来附加事件处理程序(在我看来非常难看)。
关于C# 自定义 EventArgs 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/859895/