我有一个自定义集合,我正在添加一个ValidateItem事件。只要在自定义集合中添加或更新项目,就会调用此ValidateItem事件。
我想允许派生类能够订阅事件并确定它们自己的逻辑,以确定某个项是否“有效”,如果它是“无效”,则可能禁止将其添加到集合中。
但我正在试图弄清楚如何让活动的来电者知道发生了什么,以及如何传递有关背景的信息。
我的自定义eventargs继承自CancelEventArgs,因此我可以使用它将Cancel位传回给调用者。但我从未见过以这种方式传递错误信息(错误代码,消息等)的任何情况,所以我想知道这可能不是最好的方法。
我是否应该添加我希望传递回Custom 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)
派生类中的方法。虽然我倾向于避免退出参数......
如果有人对每种方法的利弊有任何想法,我很乐意听到它们!
谢谢, 最大
答案 0 :(得分:3)
使用事件可能不是最好的设计方法。
由于它是一个覆盖此行为的继承类,因此该方法应标记为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;
}
使用此事件的优缺点是,当您要向多个订阅者发布操作或信息时,将使用事件。订阅者是您不了解的类。你不在乎他们是谁或他们做了什么。他们不应该真正将信息传递给通知类。他们应该只处理提供给他们的事件信息。
在您的实例中,您继承的类是您唯一的订阅者。最重要的是,您希望能够将有用的信息传递回父类。继承更好地适应这种期望的行为,并且还允许您轻松实现不同类型的验证类。对于事件,您必须不断输入代码来反复附加事件处理程序(非常丑陋的IMO)。
答案 1 :(得分:1)
我不认为你所描述的内容真的适合你通常会在活动中看到的观察者,可观察的模式。
由于这些是派生类,我可能希望虚拟化对象的验证方法并让子代提供特定的验证例程。
答案 2 :(得分:0)
好吧,如果您创建自己的自定义验证事件以及自定义验证事件参数,我会假设您更愿意传回状态/错误代码,而不是在某些内容无法验证时抛出异常。
在这种情况下,如果你想进行不会抛出异常的验证,那么是的,我会将你需要的那些字段添加到自定义事件args中 - 它们已经是自定义的,所以没有理由不扩展它们以满足您的需求: - )
马克
答案 3 :(得分:0)
一些敏捷的想法:
我会使属性readonly符合eventargs类的“正常”模式。
也许与错误信息相关的属性应该包含在一些ErrorInformation类中(这样可以更容易地将这些信息传递给其他方法)。
一个问题:你如何使用EventArgs属性?
答案 4 :(得分:0)
自定义事件args专门用于向事件处理程序传递信息,因此,是的,它们是放置它们的好地方。
另一种选择是抛出异常 - 这是相当苛刻的,但应该阻止其他事件处理程序被执行。
答案 5 :(得分:0)
EventArgs和CancelEventArgs没有任何成员将信息传递给订阅者。 因此,您通常会继承其中一个类并添加一个或多个成员来传递信息。 您还可以使您的类具有通用性,这样,只要您有不同的数据要发送,就不必创建新的EventArgs类。
最后,您可以使用EventHandler<T>
,而不是创建自己的ItemValidationEventHandler委托类型,其中T是EventArgs参数的类型。
此外,您不需要EventArgs = e成员。