Предупреждение Visual Studio 2008 об изменениях кода, созданного конструктором

Этот вопрос немного анекдотичен, но мне все же интересен; Мне было интересно, почему Visual Studio 2008 не любит следующее использование констант:

public class Service101 : ServiceBase
{
    /// <remarks>
    /// Shown at Start -> Settings -> Control Panel -> Administrative Tools -> Services
    /// </remarks>
    internal const string SERVICE_NAME = "WinSvc101";
    /// <remarks>
    /// Shown at Start -> Settings -> Control Panel -> Administrative Tools -> Services
    /// </remarks>
    internal const string DISPLAY_NAME = "Windows Service 101";
    /// <summary>
    /// Public constructor for Service101.
    /// </summary>      
    public Service101()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        this.ServiceName = Service101.SERVICE_NAME;
        this.EventLog.Source = Service101.DISPLAY_NAME;
        this.EventLog.Log = "Application";

        if (!EventLog.SourceExists(Service101.DISPLAY_NAME))
        {
            EventLog.CreateEventSource(Service101.DISPLAY_NAME, "Application");
        }
    }
    #region Events
    /// <summary>
    /// Dispose of objects that need it here.
    /// </summary>
    /// <param name="disposing">Whether or not disposing is going on.</param>
    protected override void Dispose(bool disposing)
    {
        // TODO: Add cleanup code here (if required)
        base.Dispose(disposing);
    }

Поскольку во время разработки отображается следующее Предупреждение:

Warning 1   The designer cannot process the code at line 68: 

if (!EventLog.SourceExists(DISPLAY_NAME))
{
    EventLog.CreateEventSource(DISPLAY_NAME, "Application");
}

The code within the method 'InitializeComponent' is generated by the designer and should not be manually modified.  Please remove any changes and try opening the designer again.   E:\Proyectos\beanstalk\dotnetfx\trunk\WinSvc101\WinSvc101\Service101.cs 69  0   

Любой комментарий был бы очень признателен. Большое спасибо заранее.


person Nano Taboada    schedule 26.07.2009    source источник


Ответы (4)


Дизайнер недоволен, когда вы добавляете код в InitializeComponent(). Вместо этого попробуйте что-то вроде этого:

public Service101()
{
    InitializeComponent();
    this.createEventSource();
}

private void InitializeComponent()
{
    this.ServiceName = SERVICE_NAME;
    this.EventLog.Source = DISPLAY_NAME;
    this.EventLog.Log = "Application";
}

void createEventSource()
{
    if (!EventLog.SourceExists(DISPLAY_NAME))
    {
        EventLog.CreateEventSource(DISPLAY_NAME, "Application");
    }
}
person Andrew Hare    schedule 26.07.2009
comment
Андрей, большое спасибо за комментарий! Теперь с вашими изменениями сообщения меняются на: Предупреждение 1. Переменная 'SERVICE_NAME' либо не объявлена, либо никогда не назначалась. Предупреждение 2. Переменная DISPLAY_NAME либо не объявлена, либо никогда не назначалась. - person Nano Taboada; 26.07.2009
comment
Чтобы устранить предупреждение, мне пришлось использовать Service101.SERVICE_NAME и Service101.DISPLAY_NAME соответственно. - person Nano Taboada; 27.07.2009

Это на самом деле сказал вам. Этот код генерируется дизайнером. Дизайнеру нужно, чтобы он был таким, каким он его оставил. Не изменяйте этот код, если только вы не хотите, чтобы дизайнер делал с ним неприятные вещи.


Существует своего рода равновесие между тем, что вы видите в визуальном дизайнере, и кодом, который он сгенерировал.

  1. Вы начинаете с пустой области дизайна, поэтому нет сгенерированного кода.
  2. Вы перетаскиваете что-то на поверхность конструктора. Дизайнер генерирует код, необходимый для его создания.
  3. Вы задаете свойства этого объекта, а дизайнер генерирует код, который задает указанные вами свойства.
  4. Вы сохраняете и закрываете
  5. Вы повторно открываете документ в дизайнере. Дизайнер должен выяснить, что отображать на рабочей поверхности. Он считывает сгенерированный код, и, поскольку он знает, что код был сгенерирован сам, он знает, что этот код означает с точки зрения поверхности проектирования.
  6. В следующий раз при изменении или сохранении код будет сгенерирован повторно.

Теперь предположим, что вы внесли некоторые изменения в сгенерированный код. Если вы не внесете это изменение точно так же, как это сделал бы дизайнер, он не распознает это изменение. Ваше изменение не будет отображаться в области конструктора. В следующий раз при изменении или сохранении дизайнер создаст код заново без ваших изменений.

Поэтому, если вы не хотите потерять изменения в сгенерированном коде, не вносите в него никаких изменений.

person John Saunders    schedule 26.07.2009
comment
Это все хорошо, но не совсем помогает решить что-либо. Основной вопрос заключается в том, что на самом деле запускает и видит дизайнер. Я только что открыл какой-то старый код, который загружает и заполняет несколько полей пользовательского интерфейса из файла конфигурации, и дизайнер, похоже, даже не видит и не выполняет неконстантные назначения для собственных приватов формы. - person ZXX; 12.10.2010
comment
@ZXX: Дело в том, что дизайнер создал этот код, и дизайнер делает с этим кодом, что хочет - не трогайте его, если только вы не дизайнер. - person John Saunders; 13.10.2010
comment
За исключением того, что в реальной жизни вы должны. Люди задают такие вопросы, надеясь узнать некоторые механизмы того, что разумно выполнимо, так что честь твоего лорда на самом деле не поможет. Всегда можно сделать резервную копию и сравнить, если дизайнер действительно что-то напутал, но нужно знать, сколько он может изменить, прежде чем дизайнер откажется загружаться, чтобы вы могли видеть визуальное соответствие. Похоже, задействован пользовательский сериализатор. Я вижу new-s honored и даже массивные назначения, но не статику, или, может быть, просто статику CLR, или, может быть, объект из ссылочных dll-ов, но не из текущей сборки... - person ZXX; 13.10.2010
comment
@ZXX: Microsoft задокументировала набор разумных изменений, которые вы можете внести в код, созданный дизайнером. Набор пустой. Если вы обнаружите, что вам нужно изменить сгенерированный код, значит, вы делаете что-то не так, и вам следует обратиться за помощью. НИКОГДА не изменяйте сгенерированный код. Помогут ли вам частичные занятия? - person John Saunders; 13.10.2010
comment
Если бы мои документы когда-либо были моими ограничениями, я бы до сих пор блокировал Hashtables :-) Реальность берет верх, и она говорит, что я возился с кодом от кого-то, кто создает новые winforms наизнанку, поэтому ему не нужен хромой дизайнер, и он сделал несколько вещей, чтобы остановить это :-) Но я делаю, так как я бэкэнд-разработчик, нуждающийся в быстром исправлении. Резервное копирование и сравнение для меня естественны, и мне нужно получить как можно больше информации о серой зоне в кратчайшие сроки. Каждый раз, когда я касаюсь этого кода, я теряю производительность, поэтому я все равно собираюсь отменить большинство изменений. Вы можете увидеть это на странице webservicestudio.codeplex.com/SourceControl/list/changesets. - person ZXX; 15.10.2010
comment
Между прочим, разбор автогена — довольно распространенная практика для высокопроизводительных кодовых баз, где вы должны обосновывать каждую измененную строку, и автоген сделал это так же важно, как это сделал кот. Мои фавориты по-прежнему от xsd и linq, но они в одну сторону, так что проще. Здесь нам нужен раздел autogen-modder :-) Также есть много полезного для изучения. - person ZXX; 15.10.2010

Мне кажется вполне понятным. Он говорит вам, что вы изменили автоматически сгенерированный код, и вам не следует этого делать.

В худшем случае вы, вероятно, можете потерять свои изменения. В лучшем случае он находит неожиданный код и ничего не меняет, поэтому вы не потеряете свои изменения. Но он также не может понять ваш код. Вы должны разместить свои константы в любом другом месте.

person raven    schedule 26.07.2009
comment
Спасибо за ваш вклад Хайме! - person Nano Taboada; 26.07.2009

Немного не по делу, но я действительно не понимаю, почему вы все равно используете константы (и общедоступные). Не могли бы вы просто сделать это?

private void InitializeComponent()
{
    this.ServiceName = "WinSvc101";
    this.EventLog.Source = "Windows Service 101";
    // ....
}
person Dan Diplo    schedule 26.07.2009
comment
Эй Дэн, большое спасибо за ваш комментарий. Чтобы ответить на ваш вопрос, я использую там константы, потому что хочу гарантировать условие, при котором свойство serviceInstaller.ServiceName всегда соответствует Service101.ServiceName. Не стесняйтесь комментировать, если вы знаете лучший способ добиться этого! - person Nano Taboada; 26.07.2009
comment
В основном они общедоступны, потому что мне нужно использовать их и в другом классе. - person Nano Taboada; 26.07.2009
comment
Вместо public вы можете использовать internal - таким образом, они доступны внутри ваших классов, но не снаружи. Когда я писал Службы, я обычно сохранял значения конфигурации в специальном файле app.config, а затем считывал их в статические внутренние свойства при запуске службы. Затем эти свойства становятся доступными для ваших классов, но не выставляются на всеобщее обозрение. Конечно, может быть и лучший способ - я не эксперт! Удачи. Для app.config см.: geekswithblogs.net/akraus1 статьи/64871.aspx - person Dan Diplo; 26.07.2009
comment
Большое спасибо за комментарий! Я изменил комментарий с помощью модификаторов internal. - person Nano Taboada; 27.07.2009