Я запускаю статический анализ кода с помощью FxCop 1.36, и я продолжаю получать предупреждение CA1034: NestedTypesShouldNotBeVisible.
Я бы понял, был ли родительский класс объявлен как внутренний или закрытый, но он общедоступен. Почему было бы плохо, если TimerReset будет объявлен публичным?
Я что-то упускаю, или это то, что можно игнорировать?
Спасибо за любой вклад!
Вот фрагмент кода, вызывающий это предупреждение:
namespace Company.App.Thing
{
public partial class Page : XtraPage
{
public delegate void TimerResetDelegate(object sender, EventArgs e);
private TimerResetDelegate _timerReset;
public Page()
{
InitializeComponent();
}
public TimerResetDelegate TimerReset
{
set
{
if (null != (_timerReset = value))
{
checkBox.Click += new EventHandler(_timerReset);
textField.Click += new EventHandler(_timerReset);
textField.KeyDown += new KeyEventHandler(_timerReset);
TimeField.Click += new EventHandler(_timerReset);
TimeField.KeyDown += new KeyEventHandler(_timerReset);
}
}
}
}
}
Вообще говоря, вложенные типы сложнее "обнаружить".
например. Чтобы использовать ваш вложенный тип, мне придется писать следующие
Page.TimerResetDelegate timer = new Page.TimerResetDelegate();
Несмотря на то, что выше допустимый код С#, он не читается, как обычный тип использования.
Вложенные типы обычно используются, когда вы хотите определить тип, который будет использоваться внутри, и вы избегаете кода, как указано выше. Именно по этой причине FxCop дает вам предупреждение. Если вы хотите, вы можете игнорировать его. Лично я бы сохранил свои вложенные типы как приватные. Если я ожидаю, что вызывающий абонент будет использовать этот тип, я переведу их в соответствующее пространство имен.
Почему для объявления TimerReset было бы плохо публично?
Именно в качестве описания указано:
Вложенные типы полезны для инкапсуляции частных деталей реализации содержащего типа. Используемые для этой цели вложенные типы не должны быть внешне видимыми.
Поскольку вы публикуете TimerResetDelegate
публично с помощью TimerReset
, я предполагаю, что это не детализация реализации.
Не использовать внешние видимые вложенные типы для логической группировки или избегать коллизий имен; вместо этого используйте пространства имен.
Это делает его похожим на то, что вы используете вложенный тип для группировки. В качестве состояний FxCop вместо этого используйте пространство имен.
Вложенные типы включают понятие доступности участника, которое некоторые программисты не понимают четко.
Так как TimerResetDelegate
является делегатом, это не применимо.
Переместите TimerResetDelegate
в свой собственный файл TimeResetDelegate.cs и поместите его в пространство имен Company.App.Thing
. Затем он больше не вложен.
Конечно, было бы еще лучше просто пойти с EventHandler вместо определения вашего собственного типа делегата.
Это потому, что ваш делегат является типом, но он определен в классе Page. Я бы просто определил его в пространстве имен Company.App.Thing, но это не проблема. Если бы вы писали API, это просто сделало бы его немного грязным, все.
Кроме того, немного странно возвращать делегат, как это, но я думаю, что я действительно не знаю, чего вы пытаетесь выполнить.
IMHO, это правило FxCop, которое можно игнорировать.
С уровня CLR нет ничего плохого, имея вложенный класс. Это просто правило правил, добавленное к FxCop, потому что авторы считают, что он менее полезен или имеет более плохую конструкцию, чем делает класс не-вложенным.
По-видимому, это не нравится идея вложенных классов, когда они могут использоваться вне контекста вашего класса страницы.
Я лично согласен с этим в принципе, хотя я могу представить некоторые исключения, где это может быть желательно.
EventHandler
?