, предшествующих сообщений:Код для печати Версия для подписи событий в .NET
Event Signature in .NET — Using a Strong Typed 'Sender'?
In a C# event handler, why must the “sender” parameter be an object?
пользователи конвенции и рекомендации силы .NET от Microsoft использовать специальный шаблон для создания, повышения и обработки событий в .NET.
принципы дизайна событий http://msdn.microsoft.com/en-us/library/ms229011.aspx заявляют, что
Образец цитирования:
событие-обработчик подписи соблюдает следующие условные обозначения:
Возвращаемый тип Пустота.
Первый параметр называется отправитель и имеет тип Object. Это объект , который поднял событие.
Второй параметр называется е и имеет EventArgs типа или производный класс EventArgs.This является событий конкретных данных в.
Метод принимает ровно два параметра .
Эти конвенции говорят разработчики, что (далее) короче и более очевидным код зла:
public delegate void ConnectionEventHandler(Server sender, Connection connection);
public partial class Server
{
protected virtual void OnClientConnected(Connection connection)
{
if (ClientConnected != null) ClientConnected(this, connection);
}
public event ConnectionEventHandler ClientConnected;
}
и (следующие) более и менее очевидным код хорош:
public delegate void ConnectionEventHandler(object sender, ConnectionEventArgs e);
public class ConnectionEventArgs : EventArgs
{
public Connection Connection { get; private set; }
public ConnectionEventArgs(Connection connection)
{
this.Connection = connection;
}
}
public partial class Server
{
protected virtual void OnClientConnected(Connection connection)
{
if (ClientConnected != null) ClientConnected(this, new ConnectionEventArgs(connection));
}
public event ConnectionEventHandler ClientConnected;
}
Хотя в этих рекомендациях не указано, почему так важно следовать этим соглашениям, заставляя разработчиков действовать как обезьяны которые не знают, почему и что они делают.
IMHO, конвенция подписи события от Microsoft для .NET плоха для вашего кода, потому что они вызывают дополнительные усилия с нулевым КПД тратиться на кодирование, кодирование, кодирование:
- Coding «(MyObject) отправитель» слепки (не говоря уже о 99% ситуаций, которые вообще не требуют отправителя)
- Кодирование, полученное из «MyEventArgs» для данных, передаваемых внутри обработчика событий.
- Условные обозначения кодирования (вызов «e.MyData», когда данные необходимы, а не только„данных“)
Это не так трудно сделать это усилие, но практически говоря, что мы потерять, когда не соответствующие конвенции Microsoft, за исключением того, что люди принимают вас как еретик, потому что ваш акт конфронтации к конвенциям от Microsoft verges on blasphemy :)
согласны ли вы?
В качестве побочного примечания эта строка является чистым злом: 'if (ClientConnected! = Null) ClientConnected (...);'. Вы никогда не должны, * когда-либо * вызывать такие события, потому что он предполагает, что никто никогда не удалит обработчик событий из другого потока. Вы рискуете выбросить NRE здесь. Вместо этого вы должны: var h = ClientConnected; if (h! = null) h (...); '. – cdhowie
К сожалению, cdhowie ваше решение для безопасности потока событий не будет работать. Пожалуйста, проверьте «неправильное решение # 2, из Руководства каркаса и MSDN» http://www.codeproject.com/Articles/37474/Threadsafe-Events.aspx (у меня не было никаких намерений делает этот поток событий безопасно, это только ради примера) Но спасибо в любом случае. – Lu4
Хороший читать Lu4, спасибо. – cdhowie